#include #include "flipDB.h" #include "palmUtil.h" //#include "flipMain.h" /* Get the number of words in the database. */ extern UInt16 GetNumWords(DmOpenRef dbR) { UInt16 n; UtilDBSize(dbR, &n); return n; } /* Get a pointer to one of the words in an entry. */ extern char *GetWordPtr(PackedWord *packed, Boolean whichWord) { if (!whichWord) { return &packed->word1[0]; } else { return &packed->word1[StrLen(packed->word1) + 1]; } } /* Checks if a record is marked as known. */ extern UInt8 IsKnown(DmOpenRef dbR, UInt16 index) { MemHandle recordH; PackedWord *packed; UInt8 known; recordH = DmQueryRecord(dbR, index); packed = MemHandleLock(recordH); known = packed->known; MemHandleUnlock(recordH); return known; } /* Set the known state of a word in the current list by word index. */ extern void SetKnown(DmOpenRef dbR, UInt16 index, UInt8 known) { MemHandle recordH; PackedWord *packed; recordH = DmGetRecord(dbR, index); packed = MemHandleLock(recordH); DmWrite(packed, offsetof(PackedWord, known), &known, sizeof(packed->known)); MemHandleUnlock(recordH); DmReleaseRecord(dbR, index, true); } /* Set the known state of all words in the current list. */ extern void SetAllKnown(DmOpenRef dbR, UInt8 known) { int i, numWords; numWords = GetNumWords(dbR); for (i = 0; i < numWords; i++) { SetKnown(dbR, i, known); } } /* Allocates a new handle and copies some data to it. */ static MemHandle CopyToNewHandle(MemPtr srcP, int len) { MemHandle destH; MemPtr destP; destH = MemHandleNew(len); destP = MemHandleLock(destH); MemMove(destP, srcP, len); MemHandleUnlock(destH); return destH; } /* * Copies the contents of a handle to a record, returns number of bytes copied. */ static UInt32 CopyHandleToRecord(MemPtr dstP, UInt32 offset, MemHandle srcH) { UInt32 size; MemPtr srcP; size = MemHandleSize(srcH); srcP = MemHandleLock(srcH); DmWrite(dstP, offset, srcP, size); MemHandleUnlock(srcH); return size; } /* * Unpacks a word from the database, allocating the neccessary handles. */ extern void UnpackWord(MemHandle recordH, UnpackedWord *unpacked) { PackedWord *packed; UInt16 size1; UInt16 size2; char *word2; ErrFatalDisplayIf(unpacked->valid, "Tried to pack to valid UnpackedWord."); packed = MemHandleLock(recordH); unpacked->known = packed->known; size1 = StrLen(packed->word1) + 1; unpacked->word1 = CopyToNewHandle(packed->word1, size1); word2 = &packed->word1[size1]; size2 = StrLen(word2) + 1; unpacked->word2 = CopyToNewHandle(word2, size2); unpacked->valid = true; MemHandleUnlock(recordH); } /* Frees the handles in the structure (not the structure itself). */ extern void FreeUnpackedWord(UnpackedWord * unpacked) { ErrFatalDisplayIf(!unpacked->valid, "Tried to free invalid UnpackedWord."); MemHandleFree(unpacked->word1); unpacked->word1 = NULL; MemHandleFree(unpacked->word2); unpacked->word2 = NULL; unpacked->valid = false; } /* * Packs a word into the database * recordH must be marked busy before calling this routine * Parameters: * unpacked: the handles in this structure will be freed. */ extern void PackWord(MemHandle recordH, UnpackedWord *unpacked) { PackedWord *packed; UInt32 size; UInt32 size1; UInt32 size2; Err err; UInt32 offset; ErrFatalDisplayIf(!unpacked->valid, "Tried to pack invalid UnpackedWord."); size1 = MemHandleSize(unpacked->word1); size2 = MemHandleSize(unpacked->word2); size = sizeof(unpacked->known) + size1 + size2; // resize to fit new data err = MemHandleResize(recordH, size); if (!err) { // not saving if no memory packed = MemHandleLock(recordH); offset = offsetof(PackedWord, known); DmWrite(packed, offset, &unpacked->known, sizeof(unpacked->known)); offset += sizeof(unpacked->known); offset += CopyHandleToRecord(packed, offset, unpacked->word1); offset += CopyHandleToRecord(packed, offset, unpacked->word2); MemHandleUnlock(recordH); } FreeUnpackedWord(unpacked); } /* Add a word to the database. Returns the record index of the new record. */ extern Err AddWord(DmOpenRef dbR, UInt16 *indexPtr, char *word1, char *word2) { Err err; MemHandle recordH; MemPtr recordP; UInt16 index; UInt16 offset; Int16 size1, size2; size1 = StrLen(word1); size2 = StrLen(word2); // Allocate a chunk in the database for the new record. recordH = DmNewHandle(dbR, (UInt32) (size1 + size2 + 3)); if (recordH == NULL) return dmErrMemError; // Pack the the data into the new record. recordP = MemHandleLock(recordH); offset = 0; DmSet(recordP, offset, 1, 0); // known = 0 offset += 1; DmStrCopy(recordP, offset, word1); offset += size1 + 1; DmStrCopy(recordP, offset, word2); MemPtrUnlock(recordP); // Attach the record. index = dmMaxRecordIndex; err = DmAttachRecord(dbR, &index, recordH, NULL); if (err) { MemHandleFree(recordH); return err; } if (indexPtr != NULL) { *indexPtr = index; } return errNone; } /* Remove a record from the database. */ extern Err RemoveWord(DmOpenRef dbR, UInt16 index) { return DmRemoveRecord(dbR, index); } /* Get the number of word lists. */ extern Err FlipNumDatabases(UInt16 *numDBs) { UInt16 i; Boolean newSearch = true; DmSearchStateType state; UInt16 cardNo; LocalID dbID; Err err; for (i = 0;; i++) { err = DmGetNextDatabaseByTypeCreator(newSearch, &state, flipDbType, flipCreatorId, false, &cardNo, &dbID); if (!dbID) { *numDBs = i; return errNone; } if (err) return err; newSearch = false; } } /* * Get metadata about a wordlist. * Parameters: * index: The number of the word list to get info about * info: Pointer to a structure where the info wil be stored. * Returns: dmErrCantFind if there is no database with the given index. */ extern Err FlipGetDatabase(UInt16 index, FlipDBInfo *info) { UInt16 i; Boolean newSearch = true; DmSearchStateType state; UInt16 cardNo; LocalID dbID; Err err; for (i = 0; i <= index; i++) { err = DmGetNextDatabaseByTypeCreator(newSearch, &state, flipDbType, flipCreatorId, false, &cardNo, &dbID); if (err) return err; newSearch = false; } info->cardNo = cardNo; info->dbID = dbID; err = DmDatabaseInfo(cardNo, dbID, info->name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (err) return err; return errNone; } /* * Close the current word list and open another. * Parameters: * info: db metadata is returned here * index: index of database to open */ extern Err SwitchDB(DmOpenRef *dbRPtr, FlipDBInfo *info, UInt16 index) { DmOpenRef dbR; Err err; err = FlipGetDatabase(index, info); if (err) return err; dbR = DmOpenDatabase(info->cardNo, info->dbID, dmModeReadWrite); if (!dbR) return dmErrCantFind; if (*dbRPtr) { err = DmCloseDatabase(*dbRPtr); /* ignoring errors */ } *dbRPtr = dbR; return errNone; } /* * Get metadata about an open database. * Parameters: * info: pointer to structure where the metadata will be returned. */ extern Err FlipGetOpenDatabase(DmOpenRef dbR, FlipDBInfo *info) { Err err; err = DmOpenDatabaseInfo(dbR, &info->dbID, NULL, NULL, &info->cardNo, NULL); if (err) return err; err = DmDatabaseInfo(info->cardNo, info->dbID, info->name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (err) return err; return errNone; } /* * Get the word list number of a database. * Parameters: * index: will put the word list number here * info: metadata used to find the database. */ extern Err FlipGetDatabaseIndex(UInt16 *index, FlipDBInfo *info) { UInt16 i; Boolean newSearch = true; DmSearchStateType state; UInt16 cardNo; LocalID dbID; Err err; for (i = 0;; i++) { err = DmGetNextDatabaseByTypeCreator(newSearch, &state, flipDbType, flipCreatorId, false, &cardNo, &dbID); if (err) return err; if (!dbID) return dmErrCantFind; if (cardNo == info->cardNo && dbID == info->dbID) { *index = i; return errNone; } newSearch = false; } } /* Create a new empty word list.*/ extern Err CreateEmptyDB(void) { return DmCreateDatabase(0, flipDbName, flipCreatorId, flipDbType, false); }