From: Petteri Aimonen Date: Wed, 6 Feb 2013 19:44:40 +0000 (+0200) Subject: Avoid unnecessary looping in required fields check. X-Git-Tag: 3.99.1~14^2~417 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=commitdiff_plain;h=d23939d688b36bf9b474ab9077d4a42b69b8442d;p=apps%2Flow-level-can-service.git Avoid unnecessary looping in required fields check. Results for ARM: -6% execution time, -1% code size --- diff --git a/pb_decode.c b/pb_decode.c index b664fe1..7c3407c 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -501,15 +501,34 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[ } /* Check that all required fields were present. */ - pb_field_init(&iter, fields, dest_struct); - do { - if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED && - iter.required_field_index < PB_MAX_REQUIRED_FIELDS && - !(fields_seen[iter.required_field_index >> 3] & (1 << (iter.required_field_index & 7)))) + { + /* First figure out the number of required fields by + * seeking to the end of the field array. Usually we + * are already close to end after decoding. + */ + int req_field_count; + uint8_t last_type; + int i; + do { + req_field_count = iter.required_field_index; + last_type = iter.current->type; + } while (pb_field_next(&iter)); + + /* Fixup if last field was also required. */ + if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED) + req_field_count++; + + /* Check the whole bytes */ + for (i = 0; i < (req_field_count >> 3); i++) { - PB_RETURN_ERROR(stream, "missing required field"); + if (fields_seen[i] != 0xFF) + PB_RETURN_ERROR(stream, "missing required field"); } - } while (pb_field_next(&iter)); + + /* Check the remaining bits */ + if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7)))) + PB_RETURN_ERROR(stream, "missing required field"); + } return true; }