📄 dbbufferc.nc
字号:
err = err_OutOfMemory; goto fail; } break; case kALLOC_NAME: //DEBUG("ALLOCNAME",9); //read in the name ((char *)(*mNameHand))[mLenBytes[1]] = 0; mHeaderFileState = kREAD_NAME; call MemAlloc.lock(mNameHand); if (call HeaderFileRead.read(*mNameHand, mLenBytes[1]) != SUCCESS) { err = err_EepromFailure; goto fail; } break; case kREAD_NAME: //now compare read name to actual name call MemAlloc.unlock(mNameHand); DEBUG((char *)*mNameHand, strlen((char *)*mNameHand)); if ((mNameSearch && strcmp(*mNameHand, mCurBufName) != 0) || (!mNameSearch && mCurFile != mSearchFile)) { mHeaderFileState = kSKIP_BYTES; //move on to the next file mDidFieldLen = FALSE; mNumSkipBytes = mLenBytes[2] + sizeof(Buffer); //skip the query data plus the buffer data call MemAlloc.free(mNameHand); mNameHand = NULL; post loadBufferTask(); } else { mHeaderFileState = kALLOC_QUERY; if (call MemAlloc.allocate(&mQueryHandle, mLenBytes[2]) == FAIL) { err = err_OutOfMemory; goto fail; } } break; case kSKIP_BYTES: if (mNumSkipBytes == 0) { if (!mDidFieldLen) { mDidFieldLen = TRUE; //read in the number of field info bytes to skip if (call HeaderFileRead.read(&mNumSkipBytes,1) != SUCCESS) { err = err_EepromFailure; goto fail; } } else { if (++mCurFile < mNumFiles) { mHeaderFileState = kREAD_OPEN; //check the next file post loadBufferTask(); } else { err = err_IndexOutOfBounds; goto fail; } } } else { numBytes = min(sizeof(mReadBuf), mNumSkipBytes); mNumSkipBytes -= numBytes; if (call HeaderFileRead.read(mReadBuf, numBytes) != SUCCESS) { err = err_EepromFailure; goto fail; } } break; case kALLOC_QUERY: mHeaderFileState = kREAD_QUERY; call MemAlloc.lock(mQueryHandle); if (call HeaderFileRead.read(*mQueryHandle, mLenBytes[2]) != SUCCESS) { err = err_EepromFailure; goto fail; } break; case kREAD_QUERY: //finally, read the buffer data in call MemAlloc.unlock(mQueryHandle); mHeaderFileState = kREAD_BUFFER; if (call HeaderFileRead.read(&mBuffers[mCurBufId], sizeof(Buffer)) != SUCCESS) { err = err_EepromFailure; goto fail; } break; case kREAD_BUFFER: //DEBUG("READBUFFER", 10); mBuffers[mCurBufId].name = (char **)mNameHand; mNameHand = NULL; mBuffers[mCurBufId].qh = (ParsedQuery **)mQueryHandle; mBuffers[mCurBufId].u.eeprom.isOpen = FALSE; mBuffers[mCurBufId].u.eeprom.isWrite = FALSE; mQueryHandle = NULL; //now, we have to read in the length of the extra field data (names and types for buffers) mHeaderFileState = kREAD_FIELD_LEN; if (call HeaderFileRead.read(mLenBytes, 1) != SUCCESS) { err = err_EepromFailure; goto fail; } break; case kREAD_FIELD_LEN: //now, alloc the field data, if needed if (mLenBytes[0] == 0) { mHeaderFileState = kREAD_FIELD_DATA; post loadBufferTask(); } else { mHeaderFileState = kALLOC_FIELD_DATA; if (call MemAlloc.allocate(&mNameHand, mLenBytes[0]) == FAIL) { err = err_OutOfMemory; goto fail; } } break; case kALLOC_FIELD_DATA: mHeaderFileState = kREAD_FIELD_DATA; call MemAlloc.lock(mNameHand); if (call HeaderFileRead.read(*mNameHand, mLenBytes[0]) == FAIL) { err = err_EepromFailure; goto fail; } break; case kREAD_FIELD_DATA: //finally, we're done -- set up the buffer and return if (mNameHand != NULL) call MemAlloc.unlock(mNameHand); (**mBuffers[mCurBufId].qh).tableInfo = (QueryTableHand)mNameHand; //it's ok if mNameHand is null mNameHand = NULL; mHeaderFileState = kIDLE; if (mState == kHEADER_READ) mState = kIDLE; call HeaderFileRead.close(); if (mLocalRead) readBuffer(mCurBufName, mCurBufId, err_NoError); else { DEBUG("load",4); signal DBBuffer.loadBufferDone(mCurBufName, mCurBufId, err_NoError); } break; default: break; } return; fail: headerReadFailed(err); } void headerReadFailed(TinyDBError err) { result_t r; if (mQueryHandle != NULL) { call MemAlloc.unlock(mQueryHandle); call MemAlloc.free(mQueryHandle); mQueryHandle = NULL; } if (mNameHand != NULL) { call MemAlloc.unlock(mNameHand); call MemAlloc.free(mNameHand); mNameHand = NULL; } mHeaderFileState = kIDLE; if (mState == kHEADER_READ) mState = kIDLE; mUsedBufs &= (0xFFFFFFFF ^ (1 << mCurBufId)); //mark this buffer as unused r = call HeaderFileRead.close(); if (mLocalRead) readBuffer(mCurBufName, 0, err); else signal DBBuffer.loadBufferDone(mCurBufName, 0, err); } /** Flush this buffer to disk. The basic idea is to rewrite the entire list of buffers, replacing the buffer currently named buf.name with the data in buf. If no buffer named buf exists, just append the new buffer onto the end of the old data. This is pretty complicated; for each buffer, we have to: - read it in (with loadEEPROMBuffer, which will call readBuffer when it's done) - check and see if it is named buf.name (with replaceBufferTask) - if so, overwrite it with buf (with appendBufferTask) - otherwise rewrite it (with appendBufferTask) - if buf hasn't been written the end of all buffers, (with appendBufferTask) append it to the end Note the the performance of this routine really sucks, since we do a scan of the buffer info file to get information about each buffer, and then write it out. */ TinyDBError doWrite(uint8_t buf); command TinyDBError DBBuffer.writeEEPROMBuffer(uint8_t bufId) { if (mState == kIDLE) { mDelete = FALSE; return doWrite(bufId); } else return err_ResultBufferBusy; } command TinyDBError DBBuffer.deleteEEPROMBuffer(uint8_t bufId) { if (mState == kIDLE) { mDelete = TRUE; return doWrite(bufId); } else return err_ResultBufferBusy; } TinyDBError doWrite(uint8_t buf) { fileresult_t err; //read all of the buffers, write them mState = kWRITE_BUFFER; if (buf >= kNUM_BUFS || (mUsedBufs & (1 << buf) == 0)) return err_IndexOutOfBounds; // DEBUG("writeBuf", 8); mReplaceBuf = &mBuffers[buf]; mReplaceBufId = buf; mCurWriteIdx = 0; mLocalRead = TRUE; mFoundBuffer = FALSE; if ((err = call HeaderFileWrite.open("tdbBufs2", FS_FCREATE | FS_FTRUNCATE)) != SUCCESS) { mState = kIDLE; return err_EepromFailure; } else return err_NoError; } //Write the count of the number of buffers to the "numBuffers" file" TinyDBError writeFileCount() { if (mState == kIDLE) { mState = kWRITE_FILE_COUNT; if (call HeaderFileWrite.open("numBuffers", FS_FCREATE | FS_FTRUNCATE) != SUCCESS) { mState = kIDLE; return err_EepromFailure; } } else return err_ResultBufferBusy; } void writeCountDone(TinyDBError err) { //DEBUG("wrote ok", 8); if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err); else { if (mAllocing) { if (mReplaceBufId == mCurBuffer) { signal DBBuffer.allocComplete(mCurBuffer, err); } } else { signal DBBuffer.writeBufferDone(mReplaceBufId, err); } } } //Read the count of the number of buffers from the "numBuffers" file TinyDBError readFileCount() { if (mState == kIDLE) { mState = kREAD_FILE_COUNT; if (call HeaderFileRead.open("numBuffers") != SUCCESS) { mState = kIDLE; return err_EepromFailure; } } else return err_ResultBufferBusy; return err_NoError; } void readCountDone(TinyDBError err) { } task void appendBufferTask() { mLocalRead = TRUE; switch (mAppendState) { case kWRITING_LENGTHS: //first, write the header mAppendState = kWRITING_NAME; mLenBytes[0] = kVERSION_CODE; mLenBytes[1] = strlen(*(mAppendBuf->name)); mLenBytes[2] = call ParsedQueryIntf.pqSize(*mAppendBuf->qh); //DEBUG("LENGTHS",6); if (call HeaderFileWrite.append(mLenBytes, 3) != SUCCESS) { mAppendState = mState = kIDLE; if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } break; case kWRITING_NAME: //then write the name call MemAlloc.lock((Handle)mAppendBuf->name); //DEBUG("NAME",4); mAppendState = kWRITING_QUERY; if (call HeaderFileWrite.append(*(mAppendBuf->name), strlen(*(mAppendBuf->name))) != SUCCESS) { call MemAlloc.unlock((Handle)mAppendBuf->name); mAppendState = mState = kIDLE; if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } break; case kWRITING_QUERY: //then write the query call MemAlloc.unlock((Handle)mAppendBuf->name); call MemAlloc.lock((Handle)mAppendBuf->qh); mAppendState = kWRITING_BUFFER;/* { *//* char map[5]; *//* int i; *//* ParsedQuery *q = *(mAppendBuf->qh); *//* mDbgBuf[0] =0; *//* strcat(mDbgBuf, "w:"); *//* for (i = 0; i < q->numFields ; i++) { *//* itoa(q->queryToSchemaFieldMap[i], map, 10); *//* strcat(mDbgBuf, map); *//* strcat(mDbgBuf, ","); *//* } *//* DEBUG(mDbgBuf, strlen(mDbgBuf)); *//* } */ if (call HeaderFileWrite.append(*(mAppendBuf->qh), call ParsedQueryIntf.pqSize(*mAppendBuf->qh)) != SUCCESS) { call MemAlloc.unlock((Handle)mAppendBuf->qh); mAppendState = mState = kIDLE; if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } break; case kWRITING_BUFFER: //write the buffer data call MemAlloc.unlock((Handle)mAppendBuf->qh); mAppendState = kWRITE_FIELD_LEN; // DEBUG("BUFFER", 6); if (call HeaderFileWrite.append(mAppendBuf, sizeof(Buffer)) != SUCCESS) { mAppendState = mState = kIDLE; if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } break; case kWRITE_FIELD_LEN: //now write the extra field data length if ((**mAppendBuf->qh).tableInfo == NULL) { mAppendState = kWRITE_NEXT_BUFFER; mLenBytes[0] = 0; // no data -- length is 0 } else { mAppendState = kWRITE_FIELD_DATA; mLenBytes[0] = (uint8_t)(call MemAlloc.size((Handle)(**mAppendBuf->qh).tableInfo)); } // DEBUG("FIELDLEN", 8); if (call HeaderFileWrite.append(mLenBytes, 1) != SUCCESS) { mAppendState = mState = kIDLE; if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } break; case kWRITE_FIELD_DATA: //assume tableInfo is non-null //DEBUG("FIELDDATA", 9); call MemAlloc.lock((Handle)(**mAppendBuf->qh).tableInfo); mAppendState = kWRITE_NEXT_BUFFER; if (call HeaderFileWrite.append(*(**mAppendBuf->qh).tableInfo, mLenBytes[0]) != SUCCESS) { call MemAlloc.unlock((Handle)(**mAppendBuf->qh).tableInfo); mAppendState = mState = kIDLE; if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } break; case kWRITE_NEXT_BUFFER: //DEBUG("NEXT", 4); if ((**mAppendBuf->qh).tableInfo != NULL) call MemAlloc.unlock((Handle)(**mAppendBuf->qh).tableInfo); if (mCurWriteIdx < mNumFiles && !mFoundBuffer) { call DBBuffer.loadEEPROMBufferIdx(mCurWriteIdx); } else if (!mFoundBuffer) { mFoundBuffer = TRUE; mAppendBuf = mReplaceBuf; mAppendState = kWRITING_LENGTHS; mNumFiles++; post appendBufferTask(); } else call HeaderFileWrite.close(); break; default: break; } } task void replaceBufferTask() { mAppendState = kWRITING_LENGTHS; if (strcmp(*mBuffers[mCurBufId].name, *mReplaceBuf->name) == 0) { mFoundBuffer = TRUE; if (mDelete) { mAppendState = kWRITE_NEXT_BUFFER; //skip over it } else { mAppendBuf = mReplaceBuf; } } else { mAppendBuf = &mBuffers[mCurBufId]; } mCurWriteIdx++; post appendBufferTask(); } void readBuffer(char *bufName, uint8_t bufId, TinyDBError err) { mLocalRead = FALSE; if (err == err_NoError) { post replaceBufferTask(); //do the next one } else { if (mDelete) signal DBBuffer.deleteBufferDone(mReplaceBufId, err_EepromFailure); else signal DBBuffer.writeBufferDone(mReplaceBufId,err_EepromFailure); } } // HeaderFileRead routines event result_t HeaderFileRead.readDone(void *buffer, filesize_t nRead, fileresult_t result) { switch (mState) { case kHEADER_READ: case kWRITE_BUFFER: //can read header file while writing buffer if (mHeaderFileState != kIDLE) { if (result != FS_OK) { //DEBUG("bad open", 8); headerReadFailed(err_EepromFailure); } else { post loadBufferTask(); } } break; case kREAD_FILE_COUNT:/* { *//* char readStr[5]; */ /* mDbgBuf[0] = 0; *//* strcat(mDbgBuf, "cnt:"); *//* itoa(*(uint8_t *)buffer, readStr, 10); *//* strcat(mDbgBuf, readStr); *//* DEBUG(mDbgBuf, strlen(mDbgBuf)); *//* } */ call HeaderFileRead.close(); mState = kIDLE; //done reading if (result!= FS_OK) readCountDone(err_EepromFailure); else { readCountDone(err_NoError); //call DBBuffer.cleanupEEPROM(); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -