void Memo_WriteLen(char* cp, UInt len) { Long newsize, newalloc; Ptr RecPointer; if (!s_pMemoDb || !cp) return; newsize = s_iOffset + len + 1; if (newsize > s_iAllocSize) { // If we need more room, round up to next multiple of diAllocSize. // This idiom only works if diAllocSize is a power of 2. newalloc = (newsize + diAllocSize-1) & ~(diAllocSize-1); if (newalloc > diMaxSize) { // If we are nearly maxed out, newalloc = diMaxSize; // use what we've got. if (newsize > diMaxSize) // If we are maxed out, give it up. return; } if (s_RecHandle) (void) DmReleaseRecord(s_pMemoDb, s_iRecNum, true); s_RecHandle = DmResizeRecord(s_pMemoDb, s_iRecNum, newalloc); if (s_RecHandle) s_iAllocSize = newalloc; } if (s_RecHandle) { if ((RecPointer = MemHandleLock(s_RecHandle))) { // Write extra char at end, often it will be null termination... if (!DmWrite(RecPointer, s_iOffset, cp, len+1)) // if no error... s_iOffset += len; (void) MemPtrUnlock(RecPointer); } } }
void Memo_WriteClose(void) { MemoWriteLen("", 0); // Make sure it is null terminated. // Release handle on record, resize to amount used... if (s_RecHandle) { (void) DmReleaseRecord(s_pMemoDb, s_iRecNum, true); if (s_iOffset+1 < s_iAllocSize && (s_RecHandle = DmResizeRecord(s_pMemoDb, s_iRecNum, s_iOffset+1))) (void) DmReleaseRecord(s_pMemoDb, s_iRecNum, true); s_RecHandle = NULL; } if (s_pMemoDb) (void) DmCloseDatabase(s_pMemoDb); s_pMemoDb = NULL; }
// Save preferences previously set via ErrSet*() calls to a database. // If something goes wrong, returns an error // Possible errors: // memErrNotEnoughSpace - not enough memory to allocate needed structures // errors from Dm*() calls Err PrefsStoreWriter::ErrSavePreferences() { Err err = errNone; long blobSize; void * prefsBlob = SerializeItems(_items, _itemsCount, &blobSize); if ( NULL == prefsBlob ) return memErrNotEnoughSpace; DmOpenRef db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) { err = DmCreateDatabase(0, _dbName, _dbCreator, _dbType, false); if ( err) return err; db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) return DmGetLastErr(); } // set backup bit on the database. code adapted from DataStore.cpp // DataStore::open() if (errNone == err) { LocalID localId; UInt16 cardNo; UInt16 attribs; err = DmOpenDatabaseInfo(db, &localId, NULL, NULL, &cardNo, NULL); if (errNone != err) goto Continue; err = DmDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (errNone != err) goto Continue; if (0 != attribs & dmHdrAttrBackup) goto Continue; attribs |= dmHdrAttrBackup; err = DmSetDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); Continue: err = errNone; } UInt16 recNo = 0; UInt16 recsCount = DmNumRecords(db); MemHandle recHandle; Boolean fRecordBusy = false; Boolean fRecFound = false; void * recData; long recSize; while (recNo < recsCount) { recHandle = DmGetRecord(db, recNo); fRecordBusy = true; recData = MemHandleLock(recHandle); recSize = MemHandleSize(recHandle); if (IsValidPrefRecord(recData)) { fRecFound = true; break; } MemPtrUnlock(recData); DmReleaseRecord(db, recNo, true); fRecordBusy = false; ++recNo; } if (fRecFound && blobSize>recSize) { /* need to resize the record */ MemPtrUnlock(recData); DmReleaseRecord(db,recNo,true); fRecordBusy = false; recHandle = DmResizeRecord(db, recNo, blobSize); if ( NULL == recHandle ) return DmGetLastErr(); recData = MemHandleLock(recHandle); Assert( MemHandleSize(recHandle) == blobSize ); } if (!fRecFound) { recNo = 0; recHandle = DmNewRecord(db, &recNo, blobSize); if (!recHandle) { err = DmGetLastErr(); goto CloseDbExit; } recData = MemHandleLock(recHandle); fRecordBusy = true; } err = DmWrite(recData, 0, prefsBlob, blobSize); MemPtrUnlock(recData); if (fRecordBusy) DmReleaseRecord(db, recNo, true); CloseDbExit: // if had error before - preserve that error // otherwise return error code from DmCloseDatabase() if (err) DmCloseDatabase(db); else err = DmCloseDatabase(db); new_free( prefsBlob ); return err; }