📄 dbbufferc.nc
字号:
for (i = 0; i < numResults; i++) { rtup = call QueryResultIntf.getResultTuple(r, i, pq); if (rtup.error != err_NoError) return rtup.error; err = call QueryResultIntf.fromResultTuple(rtup, &newqr, pq); if (err != err_NoError) break; err = call RadioQueue.enqueue((QueryResultPtr)&newqr, pending); if (err != err_NoError) break; } return err; } case kATTR_BUF: case kEVENT_BUF: case kCOMMAND_BUF: case kQUERY_BUF: return err_UnsupportedBuffer; default: err = getBuf(bufferId, &buf); if (err != err_NoError) return err; break; } switch (buf->type) { case kCOMMAND: { //low byte of data should be command id! char *cmdStr = (char *)&buf->data; CommandDescPtr cmd = call CommandUse.getCommandById((uint8_t)(cmdStr[0])); if (cmd!=NULL) { ParamVals params; SchemaErrorNo schema_err; char result[1]; switch (cmd->params.numParams) { case 0: params.numParams = 0; break; case 1: //command buffer supports 1 integer (short) parameter if (cmd->params.params[0] != INT16 && cmd->params.params[0] != UINT16 && cmd->params.params[0] != INT8 && cmd->params.params[0] != UINT8) return err_UnknownError; params.numParams = 1; params.paramDataPtr[0] = &cmdStr[1]; //2nd and 3rd bytes are command param break; default: return err_InvalidIndex; } call CommandUse.invoke(cmd->name, result, &schema_err, ¶ms); } } break; case kEEPROM: if (mState != kIDLE) { return err_ResultBufferBusy; } if (!buf->u.eeprom.isOpen) { return err_BufferNotOpen; } //must do this to increment row numbers, etc. err = calcNextFreeRow(buf); if (err != err_NoError) { return err; } mState = kEEPROM_ALLOC_ROW; mCurResult = r; mCurBuffer = bufferId; *pending = TRUE; mCurRowHandle = mEepromRow; if (mEepromRow == NULL) { //+ 1 since we need an extra byte for the length if (call MemAlloc.allocate(&mEepromRow, call QueryResultIntf.resultSize(r, pq) + 1) != SUCCESS) { *pending = FALSE; mState = kIDLE; cleanupBuffer(bufferId, __LINE__); return err_EepromFailure; } } else { //+ 1 since we need an extra byte for the length if (call MemAlloc.reallocate(mEepromRow, call QueryResultIntf.resultSize(r, pq) + 1) != SUCCESS) { *pending = FALSE; mState = kIDLE; cleanupBuffer(bufferId, __LINE__); return err_EepromFailure; } } break; case kRAM: //prev = call Interrupt.disable(); if (mState != kIDLE) { //if(prev) call Interrupt.enable(); return err_ResultBufferBusy; } mState = kALLOC_ROW; //if(prev) call Interrupt.enable(); row = buf->nextFree; err = calcNextFreeRow(buf); if (err != err_NoError) { mState = kIDLE; return err; } //need to allocate the buffer for this row mCurResult = r; mCurRow = row; mCurBuffer = bufferId; *pending = TRUE; bufList = (Handle *)(*buf->u.bufdata); if (bufList[row] != NULL) { //realloc'ing can be much more efficient than allocing all over again, //especially if the results are the same size (which should be the common case) mCurRowHandle = bufList[row]; if (call MemAlloc.reallocate(bufList[row], call QueryResultIntf.resultSize(r, pq)) != SUCCESS) { *pending = FALSE; mState = kIDLE; cleanupBuffer(bufferId, __LINE__); return err_OutOfMemory; } } else { if (call MemAlloc.allocate(&mCurRowHandle, call QueryResultIntf.resultSize(r, pq)) != SUCCESS) { *pending = FALSE; mState = kIDLE; cleanupBuffer(bufferId, __LINE__); return err_OutOfMemory; } } break; default: return err_UnknownError; } return err_NoError; } /* Remove the first element from the db buffer & deallocate it (don't return it.) Use peek() to retrieve the first element without deallocating, then call pop() when finished (because peek returns a pointer into the buffer.) */ /* 1/23/02 SRM DBBuffer.pop is no longer supported! command TinyDBError DBBuffer.pop(uint8_t bufferId) { Buffer *buf; Handle data; uint16_t row; Handle *bufList; TinyDBError err = err_NoError; err = getBuf(bufferId, &buf); if (err != err_NoError) return err; if (buf->nextFull == buf->nextFree) return err_NoMoreResults; row = buf->nextFull; bufList = (Handle *)(*buf->u.bufdata); data = bufList[row]; if (data != NULL) { call MemAlloc.free(data); bufList[row] = NULL; } buf->nextFull++; if (buf->nextFull >= buf->numRows) buf->nextFull = 0; return err; } */ /** Copy the top most result in the buffer into buf @return err_NoMoreResults if no results are available @return err_UnsupportedBuffer if the buffer doesn't support peek/pop */ command TinyDBError DBBuffer.peek(uint8_t bufferId, QueryResult *qr, bool *pending) { Buffer *buf; TinyDBError err; uint16_t row; Handle *bufList; if (bufferId == kRADIO || bufferId == kATTR_BUF || bufferId == kCOMMAND_BUF || bufferId == kEVENT_BUF || bufferId == kQUERY_BUF) return err_UnsupportedBuffer; //bool prev = call Interrupt.disable(); if (mState != kIDLE) { //if (prev) call Interrupt.enable(); return err_ResultBufferBusy; } mState = kREAD_ROW; //if (prev) call Interrupt.enable(); *pending = FALSE; //DEBUG("peek", 4); err = getBuf(bufferId, &buf); if (err != err_NoError) { mState = kIDLE; goto done; } switch(buf->type) { case kRAM: row= buf->nextFull; if (row == buf->nextFree && buf->numRows != 1) { //special case single row... err = err_NoMoreResults; mState = kIDLE; goto done; } bufList = (Handle *)(*buf->u.bufdata); if (bufList[row] == NULL) { err = err_NoMoreResults; mState = kIDLE; goto done; } call QueryResultIntf.fromBytes((QueryResultPtr)*bufList[row], qr, *buf->qh); //memcpy(qr, &(*buf->u.bufdata)[row*buf->rowSize],buf->rowSize); mState = kIDLE; break; case kEEPROM:#ifdef kMATCHBOX mCurBuffer = bufferId; mCurResult = qr; *pending = TRUE; if (!buf->u.eeprom.isOpen) { if (call FileRead.open(*buf->name) == FAIL) { err = err_EepromFailure; *pending = FALSE; mState = kIDLE; } } else { if (buf->u.eeprom.isWrite) { //we can't read if it's open for writing *pending = FALSE; mState = kIDLE; err = err_BufferOpenForWriting; } else { post readEEPROMRow(); } }#else err = err_EepromFailure; *pending = FALSE; mState = kIDLE;#endif break; default: err = err_UnknownError; mState = kIDLE; } done: //mState = kIDLE; return err; }#ifdef kMATCHBOX /** Task to read a row from the EEPROM into mCurResult, assuming mCurBuffer contains the ID of the buffer to be read from and ReadFile is currently open to the file associated with the buffer. */ task void readEEPROMRow() { Buffer *buf; TinyDBError err; err = getBuf(mCurBuffer, &buf); if (err != err_NoError) { mState = kIDLE; signal DBBuffer.getComplete(mCurBuffer, mCurResult, err_UnsupportedBuffer); } switch (mState) { case kREAD_ROW: mState = kREADING_LENGTH; buf->u.eeprom.isWrite = FALSE; buf->u.eeprom.isOpen = TRUE; if (call FileRead.read(&mLen, 1) == FAIL) { mState = kIDLE; signal DBBuffer.getComplete(mCurBuffer, mCurResult, err_EepromFailure); } break; case kREADING_LENGTH: mState = kALLOC_FOR_READ; mCurRowHandle = mEepromRow; if (mEepromRow == NULL) { if (call MemAlloc.allocate(&mEepromRow, mLen) != SUCCESS) { mState = kIDLE; signal DBBuffer.getComplete(mCurBuffer, mCurResult, err_OutOfMemory); } } else { if (call MemAlloc.reallocate(mEepromRow, mLen) != SUCCESS) { mState = kIDLE; signal DBBuffer.getComplete(mCurBuffer, mCurResult, err_OutOfMemory); } } break; case kALLOC_FOR_READ: mState = kREADING_DATA; call MemAlloc.lock(mEepromRow); if (call FileRead.read(*mEepromRow, mLen) == FAIL) { mState = kIDLE; signal DBBuffer.getComplete(mCurBuffer, mCurResult, err_EepromFailure); } break; case kREADING_DATA: //HACK! -- this is fucked up -- query result now may have pointers into mEepromRow, which //will only be valid until the next call to read or write call QueryResultIntf.fromBytes((QueryResultPtr)*mEepromRow, mCurResult, *buf->qh); //unlocking here is a BAD THING -- handle may move, result may become invalid // if it has pointers into mEeprom row, which will only be the case for // certain aggregate queries. call MemAlloc.unlock(mEepromRow); { TuplePtr t; char numStr[5]; int i; call QueryResultIntf.toTuplePtr(mCurResult, *buf->qh, &t); itoa((*buf->qh)->numFields, numStr, 10); mDbgBuf[0] = 0; strcat(mDbgBuf, numStr); strcat(mDbgBuf, ","); for(i=0;i<(*buf->qh)->numFields;i++) { itoa(*(uint16_t *)(call TupleIntf.getFieldPtr(*buf->qh, t, i)), numStr, 10); if (strlen(mDbgBuf) + strlen(numStr) + 1< sizeof(mDbgBuf)) { strcat(mDbgBuf, numStr); strcat(mDbgBuf, ","); } } DEBUG(mDbgBuf, strlen(mDbgBuf)); } mState = kIDLE; signal DBBuffer.getComplete(mCurBuffer, mCurResult, err_NoError); break; default: return; } }#endif /** Copy the nth result in the buffer into buf @return err_NoMoreResults if idx > getSize() or if buffer[idx] is empty (unset) */ command TinyDBError DBBuffer.getResult(uint8_t bufferId, uint16_t idx, QueryResult *qr, bool *pending) { TinyDBError err = err_NoError; if (mState != kIDLE) { return err_ResultBufferBusy; } mState = kREAD_ROW; switch (bufferId) { //is this a special case buffer case kATTR_BUF: { TuplePtr t; char *field; if (idx >= call AttrUse.numAttrs()) { err = err_NoMoreResults; goto done; } //the tuple part of the query result t = &qr->d.t; t->notNull = 0; t->numFields = NUM_ATTR_FIELDS; //HACK -- hard code the retrieval of catalog fields // FIELD 1 : Name field = call TupleIntf.getFieldPtrNoQuery(t, 0, NUM_ATTR_FIELDS, ATTR_SIZES, ATTR_TYPES); if (field != NULL) { AttrDescPtr adp = call AttrUse.getAttrById(idx); call TupleIntf.setFieldNoQuery(t,0,NUM_ATTR_FIELDS, ATTR_SIZES, ATTR_TYPES, adp->name); } break; } default: { Buffer *buf; uint16_t size; uint16_t row; Handle *bufList; err = getBuf(bufferId, &buf); *pending = FALSE; if (err != err_NoError) goto done; if (buf->nextFull == buf->nextFree && buf->numRows != 1) { err = err_NoMoreResults; goto done; } call DBBuffer.size(bufferId, &size); if (idx >= size) { err = err_NoMoreResults; goto done; } //see comment at beginning of document for info on slot management & indexing if (buf->nextFull > buf->nextFree) { if (idx >= (buf->numRows - buf->nextFull)) { row = idx - (buf->numRows - buf->nextFull); } else row = buf->nextFull + idx; } else { row = buf->nextFull + idx; } switch (buf->type) { case kRAM: bufList = (Handle *)(*buf->u.bufdata); call QueryResultIntf.fromBytes((QueryResultPtr)*bufList[row], qr, *buf->qh); //memcpy(qr, &(*buf->u.bufdata)[row*buf->rowSize], buf->rowSize); break; default: err = err_UnknownError; } } } done: mState = kIDLE; return err; } /* Return the number of used rows in the buffer */ command TinyDBError DBBuffer.size(uint8_t bufferId, uint16_t *size) { Buffer *buf; TinyDBError err = err_NoError; switch (bufferId) { case kATTR_BUF: *size = call AttrUse.numAttrs(); return err_NoError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -