bool decodeMotorMsgContents(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) { pb_istream_t substream; bool status; if (!pb_make_string_substream(stream, &substream)) return false; status = pb_decode(&substream, fields, dest_struct); pb_close_string_substream(stream, &substream); return status; }
static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) { pb_callback_t *pCallback = (pb_callback_t*)iter->pData; #ifdef PB_OLD_CALLBACK_STYLE void *arg = pCallback->arg; #else void **arg = &(pCallback->arg); #endif if (pCallback->funcs.decode == NULL) return pb_skip_field(stream, wire_type); if (wire_type == PB_WT_STRING) { pb_istream_t substream; if (!pb_make_string_substream(stream, &substream)) return false; do { if (!pCallback->funcs.decode(&substream, iter->pos, arg)) PB_RETURN_ERROR(stream, "callback failed"); } while (substream.bytes_left); pb_close_string_substream(stream, &substream); return true; } else { /* Copy the single scalar value to stack. * This is required so that we can limit the stream length, * which in turn allows to use same callback for packed and * not-packed fields. */ pb_istream_t substream; uint8_t buffer[10]; size_t size = sizeof(buffer); if (!read_raw_value(stream, wire_type, buffer, &size)) return false; substream = pb_istream_from_buffer(buffer, size); return pCallback->funcs.decode(&substream, iter->pos, arg); } }
void processCmdMsg(pb_istream_t *streamPtr) { pb_istream_t substream; gCmdParamNum = 0; double degSec; double pos; EMotorDirection dir; if (pb_make_string_substream(streamPtr, &substream)) { MotorMsg_Cmd motorCmd = MotorMsg_Cmd_init_zero; motorCmd.params.funcs.decode = &motorCmdParamCallback; //motorCmd.params.arg = (void *) (&motorCmd.action); pb_decode(&substream, MotorMsg_Cmd_fields, &motorCmd); pb_close_string_substream(streamPtr, &substream); switch (motorCmd.action) { case MotorMsg_Cmd_Action_UNKNOWN: break; case MotorMsg_Cmd_Action_BRAKE: motorBrake(); break; case MotorMsg_Cmd_Action_FREEWHEEL: motorFreewheel(); break; case MotorMsg_Cmd_Action_RUN: degSec = getMotorParam(MotorMsg_Cmd_Param_Id_VELOCITY, gCmdParams, gCmdParamNum); dir = (getMotorParam(MotorMsg_Cmd_Param_Id_CLOCKWISE, gCmdParams, gCmdParamNum) != 0.0) ? eClockwise : eCounterClockwise; motorRun(dir, degSec); break; case MotorMsg_Cmd_Action_GOTO_POS: pos = getMotorParam(MotorMsg_Cmd_Param_Id_POSITION, gCmdParams, gCmdParamNum); degSec = getMotorParam(MotorMsg_Cmd_Param_Id_VELOCITY, gCmdParams, gCmdParamNum); dir = (getMotorParam(MotorMsg_Cmd_Param_Id_CLOCKWISE, gCmdParams, gCmdParamNum) != 0.0) ? eClockwise : eCounterClockwise; motorGotoPos(dir, pos, degSec); break; } } }
static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) { pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)]; switch (PB_HTYPE(iter->current->type)) { case PB_HTYPE_REQUIRED: return func(stream, iter->current, iter->pData); case PB_HTYPE_OPTIONAL: *(bool*)iter->pSize = true; return func(stream, iter->current, iter->pData); case PB_HTYPE_ARRAY: if (wire_type == PB_WT_STRING && PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE) { /* Packed array */ bool status; size_t *size = (size_t*)iter->pSize; pb_istream_t substream; if (!pb_make_string_substream(stream, &substream)) return false; while (substream.bytes_left && *size < iter->current->array_size) { void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size); if (!func(&substream, iter->current, pItem)) return false; (*size)++; } status = (substream.bytes_left == 0); pb_close_string_substream(stream, &substream); return status; } else { /* Repeated field */ size_t *size = (size_t*)iter->pSize; void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size); if (*size >= iter->current->array_size) PB_RETURN_ERROR(stream, "array overflow"); (*size)++; return func(stream, iter->current, pItem); } case PB_HTYPE_CALLBACK: { pb_callback_t *pCallback = (pb_callback_t*)iter->pData; if (pCallback->funcs.decode == NULL) return pb_skip_field(stream, wire_type); if (wire_type == PB_WT_STRING) { pb_istream_t substream; if (!pb_make_string_substream(stream, &substream)) return false; while (substream.bytes_left) { if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg)) PB_RETURN_ERROR(stream, "callback failed"); } pb_close_string_substream(stream, &substream); return true; } else { /* Copy the single scalar value to stack. * This is required so that we can limit the stream length, * which in turn allows to use same callback for packed and * not-packed fields. */ pb_istream_t substream; uint8_t buffer[10]; size_t size = sizeof(buffer); if (!read_raw_value(stream, wire_type, buffer, &size)) return false; substream = pb_istream_from_buffer(buffer, size); return pCallback->funcs.decode(&substream, iter->current, pCallback->arg); } } default: PB_RETURN_ERROR(stream, "invalid field type"); } }
static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) { pb_type_t type; pb_decoder_t func; type = iter->current->type; func = PB_DECODERS[PB_LTYPE(type)]; switch (PB_HTYPE(type)) { case PB_HTYPE_REQUIRED: return func(stream, iter->current, iter->pData); case PB_HTYPE_OPTIONAL: *(bool*)iter->pSize = true; return func(stream, iter->current, iter->pData); case PB_HTYPE_REPEATED: if (wire_type == PB_WT_STRING && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) { /* Packed array */ bool status = true; size_t *size = (size_t*)iter->pSize; pb_istream_t substream; if (!pb_make_string_substream(stream, &substream)) return false; while (substream.bytes_left && *size < iter->current->array_size) { void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size); if (!func(&substream, iter->current, pItem)) { status = false; break; } (*size)++; } pb_close_string_substream(stream, &substream); if (substream.bytes_left != 0) PB_RETURN_ERROR(stream, "array overflow"); return status; } else { /* Repeated field */ size_t *size = (size_t*)iter->pSize; void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size); if (*size >= iter->current->array_size) PB_RETURN_ERROR(stream, "array overflow"); (*size)++; return func(stream, iter->current, pItem); } default: PB_RETURN_ERROR(stream, "invalid field type"); } }