Tomas Johansen
/
nanopb_test
Nanopb (lightweight version of googles protobuf) test. It is not working as it should yet.
Embed:
(wiki syntax)
Show/hide line numbers
pb_decode.c
00001 /* pb_decode.c -- decode a protobuf using minimal resources 00002 * 00003 * 2011 Petteri Aimonen <jpa@kapsi.fi> 00004 */ 00005 00006 /* Use the GCC warn_unused_result attribute to check that all return values 00007 * are propagated correctly. On other compilers and gcc before 3.4.0 just 00008 * ignore the annotation. 00009 */ 00010 #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) 00011 #define checkreturn 00012 #else 00013 #define checkreturn __attribute__((warn_unused_result)) 00014 #endif 00015 00016 #define NANOPB_INTERNALS 00017 #include "pb.h" 00018 #include "pb_decode.h" 00019 00020 /************************************** 00021 * Declarations internal to this file * 00022 **************************************/ 00023 00024 /* Iterator for pb_field_t list */ 00025 typedef struct { 00026 const pb_field_t *start; /* Start of the pb_field_t array */ 00027 const pb_field_t *pos; /* Current position of the iterator */ 00028 unsigned field_index; /* Zero-based index of the field. */ 00029 unsigned required_field_index; /* Zero-based index that counts only the required fields */ 00030 void *dest_struct; /* Pointer to the destination structure to decode to */ 00031 void *pData; /* Pointer where to store current field value */ 00032 void *pSize; /* Pointer where to store the size of current array field */ 00033 } pb_field_iterator_t; 00034 00035 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; 00036 00037 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count); 00038 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); 00039 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size); 00040 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct); 00041 static bool pb_field_next(pb_field_iterator_t *iter); 00042 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag); 00043 static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter); 00044 static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter); 00045 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter); 00046 static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); 00047 static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter); 00048 static bool checkreturn find_extension_field(pb_field_iterator_t *iter); 00049 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct); 00050 static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); 00051 static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest); 00052 static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest); 00053 static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest); 00054 static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest); 00055 static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); 00056 static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); 00057 static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); 00058 static bool checkreturn pb_skip_varint(pb_istream_t *stream); 00059 static bool checkreturn pb_skip_string(pb_istream_t *stream); 00060 00061 /* --- Function pointers to field decoders --- 00062 * Order in the array must match pb_action_t LTYPE numbering. 00063 */ 00064 static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { 00065 &pb_dec_varint, 00066 &pb_dec_uvarint, 00067 &pb_dec_svarint, 00068 &pb_dec_fixed32, 00069 &pb_dec_fixed64, 00070 00071 &pb_dec_bytes, 00072 &pb_dec_string, 00073 &pb_dec_submessage, 00074 NULL /* extensions */ 00075 }; 00076 00077 /******************************* 00078 * pb_istream_t implementation * 00079 *******************************/ 00080 00081 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count) 00082 { 00083 uint8_t *source = (uint8_t*)stream->state; 00084 stream->state = source + count; 00085 00086 if (buf != NULL) 00087 { 00088 while (count--) 00089 *buf++ = *source++; 00090 } 00091 00092 return true; 00093 } 00094 00095 bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) 00096 { 00097 #ifndef PB_BUFFER_ONLY 00098 if (buf == NULL && stream->callback != buf_read) 00099 { 00100 /* Skip input bytes */ 00101 uint8_t tmp[16]; 00102 while (count > 16) 00103 { 00104 if (!pb_read(stream, tmp, 16)) 00105 return false; 00106 00107 count -= 16; 00108 } 00109 00110 return pb_read(stream, tmp, count); 00111 } 00112 #endif 00113 00114 if (stream->bytes_left < count) 00115 PB_RETURN_ERROR(stream, "end-of-stream"); 00116 00117 #ifndef PB_BUFFER_ONLY 00118 if (!stream->callback(stream, buf, count)) 00119 PB_RETURN_ERROR(stream, "io error"); 00120 #else 00121 if (!buf_read(stream, buf, count)) 00122 return false; 00123 #endif 00124 00125 stream->bytes_left -= count; 00126 return true; 00127 } 00128 00129 /* Read a single byte from input stream. buf may not be NULL. 00130 * This is an optimization for the varint decoding. */ 00131 static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf) 00132 { 00133 if (!stream->bytes_left) 00134 PB_RETURN_ERROR(stream, "end-of-stream"); 00135 00136 #ifndef PB_BUFFER_ONLY 00137 if (!stream->callback(stream, buf, 1)) 00138 PB_RETURN_ERROR(stream, "io error"); 00139 #else 00140 *buf = *(uint8_t*)stream->state; 00141 stream->state = (uint8_t*)stream->state + 1; 00142 #endif 00143 00144 stream->bytes_left--; 00145 00146 return true; 00147 } 00148 00149 pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize) 00150 { 00151 pb_istream_t stream; 00152 #ifdef PB_BUFFER_ONLY 00153 stream.callback = NULL; 00154 #else 00155 stream.callback = &buf_read; 00156 #endif 00157 stream.state = buf; 00158 stream.bytes_left = bufsize; 00159 #ifndef PB_NO_ERRMSG 00160 stream.errmsg = NULL; 00161 #endif 00162 return stream; 00163 } 00164 00165 /******************** 00166 * Helper functions * 00167 ********************/ 00168 00169 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) 00170 { 00171 uint8_t byte; 00172 uint32_t result; 00173 00174 if (!pb_readbyte(stream, &byte)) 00175 return false; 00176 00177 if (!(byte & 0x80)) 00178 { 00179 /* Quick case, 1 byte value */ 00180 result = byte; 00181 } 00182 else 00183 { 00184 /* Multibyte case */ 00185 uint8_t bitpos = 7; 00186 result = byte & 0x7F; 00187 00188 do 00189 { 00190 if (bitpos >= 32) 00191 PB_RETURN_ERROR(stream, "varint overflow"); 00192 00193 if (!pb_readbyte(stream, &byte)) 00194 return false; 00195 00196 result |= (uint32_t)(byte & 0x7F) << bitpos; 00197 bitpos = (uint8_t)(bitpos + 7); 00198 } while (byte & 0x80); 00199 } 00200 00201 *dest = result; 00202 return true; 00203 } 00204 00205 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) 00206 { 00207 uint8_t byte; 00208 uint8_t bitpos = 0; 00209 uint64_t result = 0; 00210 00211 do 00212 { 00213 if (bitpos >= 64) 00214 PB_RETURN_ERROR(stream, "varint overflow"); 00215 00216 if (!pb_readbyte(stream, &byte)) 00217 return false; 00218 00219 result |= (uint64_t)(byte & 0x7F) << bitpos; 00220 bitpos = (uint8_t)(bitpos + 7); 00221 } while (byte & 0x80); 00222 00223 *dest = result; 00224 return true; 00225 } 00226 00227 bool checkreturn pb_skip_varint(pb_istream_t *stream) 00228 { 00229 uint8_t byte; 00230 do 00231 { 00232 if (!pb_read(stream, &byte, 1)) 00233 return false; 00234 } while (byte & 0x80); 00235 return true; 00236 } 00237 00238 bool checkreturn pb_skip_string(pb_istream_t *stream) 00239 { 00240 uint32_t length; 00241 if (!pb_decode_varint32(stream, &length)) 00242 return false; 00243 00244 return pb_read(stream, NULL, length); 00245 } 00246 00247 bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) 00248 { 00249 uint32_t temp; 00250 *eof = false; 00251 *wire_type = (pb_wire_type_t) 0; 00252 *tag = 0; 00253 00254 if (!pb_decode_varint32(stream, &temp)) 00255 { 00256 if (stream->bytes_left == 0) 00257 *eof = true; 00258 00259 return false; 00260 } 00261 00262 if (temp == 0) 00263 { 00264 *eof = true; /* Special feature: allow 0-terminated messages. */ 00265 return false; 00266 } 00267 00268 *tag = temp >> 3; 00269 *wire_type = (pb_wire_type_t)(temp & 7); 00270 return true; 00271 } 00272 00273 bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) 00274 { 00275 switch (wire_type) 00276 { 00277 case PB_WT_VARINT: return pb_skip_varint(stream); 00278 case PB_WT_64BIT: return pb_read(stream, NULL, 8); 00279 case PB_WT_STRING: return pb_skip_string(stream); 00280 case PB_WT_32BIT: return pb_read(stream, NULL, 4); 00281 default: PB_RETURN_ERROR(stream, "invalid wire_type"); 00282 } 00283 } 00284 00285 /* Read a raw value to buffer, for the purpose of passing it to callback as 00286 * a substream. Size is maximum size on call, and actual size on return. 00287 */ 00288 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size) 00289 { 00290 size_t max_size = *size; 00291 switch (wire_type) 00292 { 00293 case PB_WT_VARINT: 00294 *size = 0; 00295 do 00296 { 00297 (*size)++; 00298 if (*size > max_size) return false; 00299 if (!pb_read(stream, buf, 1)) return false; 00300 } while (*buf++ & 0x80); 00301 return true; 00302 00303 case PB_WT_64BIT: 00304 *size = 8; 00305 return pb_read(stream, buf, 8); 00306 00307 case PB_WT_32BIT: 00308 *size = 4; 00309 return pb_read(stream, buf, 4); 00310 00311 default: PB_RETURN_ERROR(stream, "invalid wire_type"); 00312 } 00313 } 00314 00315 /* Decode string length from stream and return a substream with limited length. 00316 * Remember to close the substream using pb_close_string_substream(). 00317 */ 00318 bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) 00319 { 00320 uint32_t size; 00321 if (!pb_decode_varint32(stream, &size)) 00322 return false; 00323 00324 *substream = *stream; 00325 if (substream->bytes_left < size) 00326 PB_RETURN_ERROR(stream, "parent stream too short"); 00327 00328 substream->bytes_left = size; 00329 stream->bytes_left -= size; 00330 return true; 00331 } 00332 00333 void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) 00334 { 00335 stream->state = substream->state; 00336 00337 #ifndef PB_NO_ERRMSG 00338 stream->errmsg = substream->errmsg; 00339 #endif 00340 } 00341 00342 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct) 00343 { 00344 iter->start = iter->pos = fields; 00345 iter->field_index = 0; 00346 iter->required_field_index = 0; 00347 iter->pData = (char*)dest_struct + iter->pos->data_offset; 00348 iter->pSize = (char*)iter->pData + iter->pos->size_offset; 00349 iter->dest_struct = dest_struct; 00350 } 00351 00352 static bool pb_field_next(pb_field_iterator_t *iter) 00353 { 00354 bool notwrapped = true; 00355 size_t prev_size = iter->pos->data_size; 00356 00357 if (PB_ATYPE(iter->pos->type) == PB_ATYPE_STATIC && 00358 PB_HTYPE(iter->pos->type) == PB_HTYPE_REPEATED) 00359 { 00360 prev_size *= iter->pos->array_size; 00361 } 00362 00363 if (iter->pos->tag == 0) 00364 return false; /* Only happens with empty message types */ 00365 00366 if (PB_HTYPE(iter->pos->type) == PB_HTYPE_REQUIRED) 00367 iter->required_field_index++; 00368 00369 iter->pos++; 00370 iter->field_index++; 00371 if (iter->pos->tag == 0) 00372 { 00373 iter->pos = iter->start; 00374 iter->field_index = 0; 00375 iter->required_field_index = 0; 00376 iter->pData = iter->dest_struct; 00377 prev_size = 0; 00378 notwrapped = false; 00379 } 00380 00381 iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; 00382 iter->pSize = (char*)iter->pData + iter->pos->size_offset; 00383 return notwrapped; 00384 } 00385 00386 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag) 00387 { 00388 unsigned start = iter->field_index; 00389 00390 do { 00391 if (iter->pos->tag == tag && 00392 PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) 00393 { 00394 return true; 00395 } 00396 pb_field_next(iter); 00397 } while (iter->field_index != start); 00398 00399 return false; 00400 } 00401 00402 /************************* 00403 * Decode a single field * 00404 *************************/ 00405 00406 static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) 00407 { 00408 pb_type_t type; 00409 pb_decoder_t func; 00410 00411 type = iter->pos->type; 00412 func = PB_DECODERS[PB_LTYPE(type)]; 00413 00414 switch (PB_HTYPE(type)) 00415 { 00416 case PB_HTYPE_REQUIRED: 00417 return func(stream, iter->pos, iter->pData); 00418 00419 case PB_HTYPE_OPTIONAL: 00420 *(bool*)iter->pSize = true; 00421 return func(stream, iter->pos, iter->pData); 00422 00423 case PB_HTYPE_REPEATED: 00424 if (wire_type == PB_WT_STRING 00425 && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) 00426 { 00427 /* Packed array */ 00428 bool status = true; 00429 size_t *size = (size_t*)iter->pSize; 00430 pb_istream_t substream; 00431 if (!pb_make_string_substream(stream, &substream)) 00432 return false; 00433 00434 while (substream.bytes_left && *size < iter->pos->array_size) 00435 { 00436 void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size); 00437 if (!func(&substream, iter->pos, pItem)) 00438 { 00439 status = false; 00440 break; 00441 } 00442 (*size)++; 00443 } 00444 pb_close_string_substream(stream, &substream); 00445 00446 if (substream.bytes_left != 0) 00447 PB_RETURN_ERROR(stream, "array overflow"); 00448 00449 return status; 00450 } 00451 else 00452 { 00453 /* Repeated field */ 00454 size_t *size = (size_t*)iter->pSize; 00455 void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size); 00456 if (*size >= iter->pos->array_size) 00457 PB_RETURN_ERROR(stream, "array overflow"); 00458 00459 (*size)++; 00460 return func(stream, iter->pos, pItem); 00461 } 00462 00463 default: 00464 PB_RETURN_ERROR(stream, "invalid field type"); 00465 } 00466 } 00467 00468 static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) 00469 { 00470 pb_callback_t *pCallback = (pb_callback_t*)iter->pData; 00471 00472 #ifdef PB_OLD_CALLBACK_STYLE 00473 void *arg = pCallback->arg; 00474 #else 00475 void **arg = &(pCallback->arg); 00476 #endif 00477 00478 if (pCallback->funcs.decode == NULL) 00479 return pb_skip_field(stream, wire_type); 00480 00481 if (wire_type == PB_WT_STRING) 00482 { 00483 pb_istream_t substream; 00484 00485 if (!pb_make_string_substream(stream, &substream)) 00486 return false; 00487 00488 do 00489 { 00490 if (!pCallback->funcs.decode(&substream, iter->pos, arg)) 00491 PB_RETURN_ERROR(stream, "callback failed"); 00492 } while (substream.bytes_left); 00493 00494 pb_close_string_substream(stream, &substream); 00495 return true; 00496 } 00497 else 00498 { 00499 /* Copy the single scalar value to stack. 00500 * This is required so that we can limit the stream length, 00501 * which in turn allows to use same callback for packed and 00502 * not-packed fields. */ 00503 pb_istream_t substream; 00504 uint8_t buffer[10]; 00505 size_t size = sizeof(buffer); 00506 00507 if (!read_raw_value(stream, wire_type, buffer, &size)) 00508 return false; 00509 substream = pb_istream_from_buffer(buffer, size); 00510 00511 return pCallback->funcs.decode(&substream, iter->pos, arg); 00512 } 00513 } 00514 00515 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) 00516 { 00517 switch (PB_ATYPE(iter->pos->type)) 00518 { 00519 case PB_ATYPE_STATIC: 00520 return decode_static_field(stream, wire_type, iter); 00521 00522 case PB_ATYPE_CALLBACK: 00523 return decode_callback_field(stream, wire_type, iter); 00524 00525 default: 00526 PB_RETURN_ERROR(stream, "invalid field type"); 00527 } 00528 } 00529 00530 /* Default handler for extension fields. Expects a pb_field_t structure 00531 * in extension->type->arg. */ 00532 static bool checkreturn default_extension_decoder(pb_istream_t *stream, 00533 pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) 00534 { 00535 const pb_field_t *field = (const pb_field_t*)extension->type->arg; 00536 pb_field_iterator_t iter; 00537 bool dummy; 00538 00539 if (field->tag != tag) 00540 return true; 00541 00542 iter.start = field; 00543 iter.pos = field; 00544 iter.field_index = 0; 00545 iter.required_field_index = 0; 00546 iter.dest_struct = extension->dest; 00547 iter.pData = extension->dest; 00548 iter.pSize = &dummy; 00549 00550 return decode_field(stream, wire_type, &iter); 00551 } 00552 00553 /* Try to decode an unknown field as an extension field. Tries each extension 00554 * decoder in turn, until one of them handles the field or loop ends. */ 00555 static bool checkreturn decode_extension(pb_istream_t *stream, 00556 uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter) 00557 { 00558 pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; 00559 size_t pos = stream->bytes_left; 00560 00561 while (extension && pos == stream->bytes_left) 00562 { 00563 bool status; 00564 if (extension->type->decode) 00565 status = extension->type->decode(stream, extension, tag, wire_type); 00566 else 00567 status = default_extension_decoder(stream, extension, tag, wire_type); 00568 00569 if (!status) 00570 return false; 00571 00572 extension = extension->next; 00573 } 00574 00575 return true; 00576 } 00577 00578 /* Step through the iterator until an extension field is found or until all 00579 * entries have been checked. There can be only one extension field per 00580 * message. Returns false if no extension field is found. */ 00581 static bool checkreturn find_extension_field(pb_field_iterator_t *iter) 00582 { 00583 unsigned start = iter->field_index; 00584 00585 do { 00586 if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) 00587 return true; 00588 pb_field_next(iter); 00589 } while (iter->field_index != start); 00590 00591 return false; 00592 } 00593 00594 /* Initialize message fields to default values, recursively */ 00595 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) 00596 { 00597 pb_field_iterator_t iter; 00598 pb_field_init(&iter, fields, dest_struct); 00599 00600 /* Initialize size/has fields and apply default values */ 00601 do 00602 { 00603 pb_type_t type; 00604 type = iter.pos->type; 00605 00606 if (iter.pos->tag == 0) 00607 continue; 00608 00609 if (PB_ATYPE(type) == PB_ATYPE_STATIC) 00610 { 00611 /* Initialize the size field for optional/repeated fields to 0. */ 00612 if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL) 00613 { 00614 *(bool*)iter.pSize = false; 00615 } 00616 else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) 00617 { 00618 *(size_t*)iter.pSize = 0; 00619 continue; /* Array is empty, no need to initialize contents */ 00620 } 00621 00622 /* Initialize field contents to default value */ 00623 if (PB_LTYPE(iter.pos->type) == PB_LTYPE_SUBMESSAGE) 00624 { 00625 pb_message_set_to_defaults((const pb_field_t *) iter.pos->ptr, iter.pData); 00626 } 00627 else if (iter.pos->ptr != NULL) 00628 { 00629 memcpy(iter.pData, iter.pos->ptr, iter.pos->data_size); 00630 } 00631 else 00632 { 00633 memset(iter.pData, 0, iter.pos->data_size); 00634 } 00635 } 00636 else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) 00637 { 00638 continue; /* Don't overwrite callback */ 00639 } 00640 } while (pb_field_next(&iter)); 00641 } 00642 00643 /********************* 00644 * Decode all fields * 00645 *********************/ 00646 00647 bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) 00648 { 00649 uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0}; /* Used to check for required fields */ 00650 uint32_t extension_range_start = 0; 00651 pb_field_iterator_t iter; 00652 00653 pb_field_init(&iter, fields, dest_struct); 00654 00655 while (stream->bytes_left) 00656 { 00657 uint32_t tag; 00658 pb_wire_type_t wire_type; 00659 bool eof; 00660 00661 if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) 00662 { 00663 if (eof) 00664 break; 00665 else 00666 return false; 00667 } 00668 00669 if (!pb_field_find(&iter, tag)) 00670 { 00671 /* No match found, check if it matches an extension. */ 00672 if (tag >= extension_range_start) 00673 { 00674 if (!find_extension_field(&iter)) 00675 extension_range_start = (uint32_t)-1; 00676 else 00677 extension_range_start = iter.pos->tag; 00678 00679 if (tag >= extension_range_start) 00680 { 00681 size_t pos = stream->bytes_left; 00682 00683 if (!decode_extension(stream, tag, wire_type, &iter)) 00684 return false; 00685 00686 if (pos != stream->bytes_left) 00687 { 00688 /* The field was handled */ 00689 continue; 00690 } 00691 } 00692 } 00693 00694 /* No match found, skip data */ 00695 if (!pb_skip_field(stream, wire_type)) 00696 return false; 00697 continue; 00698 } 00699 00700 if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED 00701 && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) 00702 { 00703 fields_seen[iter.required_field_index >> 3] |= (uint8_t)(1 << (iter.required_field_index & 7)); 00704 } 00705 00706 if (!decode_field(stream, wire_type, &iter)) 00707 return false; 00708 } 00709 00710 /* Check that all required fields were present. */ 00711 { 00712 /* First figure out the number of required fields by 00713 * seeking to the end of the field array. Usually we 00714 * are already close to end after decoding. 00715 */ 00716 unsigned req_field_count; 00717 pb_type_t last_type; 00718 unsigned i; 00719 do { 00720 req_field_count = iter.required_field_index; 00721 last_type = iter.pos->type; 00722 } while (pb_field_next(&iter)); 00723 00724 /* Fixup if last field was also required. */ 00725 if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag) 00726 req_field_count++; 00727 00728 /* Check the whole bytes */ 00729 for (i = 0; i < (req_field_count >> 3); i++) 00730 { 00731 if (fields_seen[i] != 0xFF) 00732 PB_RETURN_ERROR(stream, "missing required field"); 00733 } 00734 00735 /* Check the remaining bits */ 00736 if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7)))) 00737 PB_RETURN_ERROR(stream, "missing required field"); 00738 } 00739 00740 return true; 00741 } 00742 00743 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) 00744 { 00745 pb_message_set_to_defaults(fields, dest_struct); 00746 return pb_decode_noinit(stream, fields, dest_struct); 00747 } 00748 00749 bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) 00750 { 00751 pb_istream_t substream; 00752 bool status; 00753 00754 if (!pb_make_string_substream(stream, &substream)) 00755 return false; 00756 00757 status = pb_decode(&substream, fields, dest_struct); 00758 pb_close_string_substream(stream, &substream); 00759 return status; 00760 } 00761 00762 /* Field decoders */ 00763 00764 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest) 00765 { 00766 uint64_t value; 00767 if (!pb_decode_varint(stream, &value)) 00768 return false; 00769 00770 if (value & 1) 00771 *dest = (int64_t)(~(value >> 1)); 00772 else 00773 *dest = (int64_t)(value >> 1); 00774 00775 return true; 00776 } 00777 00778 bool pb_decode_fixed32(pb_istream_t *stream, void *dest) 00779 { 00780 #ifdef __BIG_ENDIAN__ 00781 uint8_t *bytes = (uint8_t*)dest; 00782 uint8_t lebytes[4]; 00783 00784 if (!pb_read(stream, lebytes, 4)) 00785 return false; 00786 00787 bytes[0] = lebytes[3]; 00788 bytes[1] = lebytes[2]; 00789 bytes[2] = lebytes[1]; 00790 bytes[3] = lebytes[0]; 00791 return true; 00792 #else 00793 return pb_read(stream, (uint8_t*)dest, 4); 00794 #endif 00795 } 00796 00797 bool pb_decode_fixed64(pb_istream_t *stream, void *dest) 00798 { 00799 #ifdef __BIG_ENDIAN__ 00800 uint8_t *bytes = (uint8_t*)dest; 00801 uint8_t lebytes[8]; 00802 00803 if (!pb_read(stream, lebytes, 8)) 00804 return false; 00805 00806 bytes[0] = lebytes[7]; 00807 bytes[1] = lebytes[6]; 00808 bytes[2] = lebytes[5]; 00809 bytes[3] = lebytes[4]; 00810 bytes[4] = lebytes[3]; 00811 bytes[5] = lebytes[2]; 00812 bytes[6] = lebytes[1]; 00813 bytes[7] = lebytes[0]; 00814 return true; 00815 #else 00816 return pb_read(stream, (uint8_t*)dest, 8); 00817 #endif 00818 } 00819 00820 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) 00821 { 00822 uint64_t value; 00823 if (!pb_decode_varint(stream, &value)) 00824 return false; 00825 00826 switch (field->data_size) 00827 { 00828 case 1: *(int8_t*)dest = (int8_t)value; break; 00829 case 2: *(int16_t*)dest = (int16_t)value; break; 00830 case 4: *(int32_t*)dest = (int32_t)value; break; 00831 case 8: *(int64_t*)dest = (int64_t)value; break; 00832 default: PB_RETURN_ERROR(stream, "invalid data_size"); 00833 } 00834 00835 return true; 00836 } 00837 00838 bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest) 00839 { 00840 uint64_t value; 00841 if (!pb_decode_varint(stream, &value)) 00842 return false; 00843 00844 switch (field->data_size) 00845 { 00846 case 4: *(uint32_t*)dest = (uint32_t)value; break; 00847 case 8: *(uint64_t*)dest = value; break; 00848 default: PB_RETURN_ERROR(stream, "invalid data_size"); 00849 } 00850 00851 return true; 00852 } 00853 00854 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) 00855 { 00856 int64_t value; 00857 if (!pb_decode_svarint(stream, &value)) 00858 return false; 00859 00860 switch (field->data_size) 00861 { 00862 case 4: *(int32_t*)dest = (int32_t)value; break; 00863 case 8: *(int64_t*)dest = value; break; 00864 default: PB_RETURN_ERROR(stream, "invalid data_size"); 00865 } 00866 00867 return true; 00868 } 00869 00870 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) 00871 { 00872 UNUSED(field); 00873 return pb_decode_fixed32(stream, dest); 00874 } 00875 00876 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) 00877 { 00878 UNUSED(field); 00879 return pb_decode_fixed64(stream, dest); 00880 } 00881 00882 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) 00883 { 00884 pb_bytes_array_t *x = (pb_bytes_array_t*)dest; 00885 00886 uint32_t temp; 00887 if (!pb_decode_varint32(stream, &temp)) 00888 return false; 00889 x->size = temp; 00890 00891 /* Check length, noting the space taken by the size_t header. */ 00892 if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes)) 00893 PB_RETURN_ERROR(stream, "bytes overflow"); 00894 00895 return pb_read(stream, x->bytes, x->size); 00896 } 00897 00898 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) 00899 { 00900 uint32_t size; 00901 bool status; 00902 if (!pb_decode_varint32(stream, &size)) 00903 return false; 00904 00905 /* Check length, noting the null terminator */ 00906 if (size + 1 > field->data_size) 00907 PB_RETURN_ERROR(stream, "string overflow"); 00908 00909 status = pb_read(stream, (uint8_t*)dest, size); 00910 *((uint8_t*)dest + size) = 0; 00911 return status; 00912 } 00913 00914 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest) 00915 { 00916 bool status; 00917 pb_istream_t substream; 00918 const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr; 00919 00920 if (!pb_make_string_substream(stream, &substream)) 00921 return false; 00922 00923 if (field->ptr == NULL) 00924 PB_RETURN_ERROR(stream, "invalid field descriptor"); 00925 00926 /* New array entries need to be initialized, while required and optional 00927 * submessages have already been initialized in the top-level pb_decode. */ 00928 if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) 00929 status = pb_decode(&substream, submsg_fields, dest); 00930 else 00931 status = pb_decode_noinit(&substream, submsg_fields, dest); 00932 00933 pb_close_string_substream(stream, &substream); 00934 return status; 00935 } 00936
Generated on Thu Jul 14 2022 19:55:28 by 1.7.2