dict_tools.c (2762B)
1 /* 2 * Copyright (c) 2016, Natacha Porté 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <inttypes.h> 18 19 #include "dict_tools.h" 20 21 static bool 22 check_length(Tuple *tuple, const char *context) { 23 if (tuple->length == 1 || tuple->length == 2 || tuple->length == 4) { 24 return true; 25 } 26 27 APP_LOG(APP_LOG_LEVEL_ERROR, 28 "Unexpected length %" PRIu16 " in %s dictionary entry", 29 tuple->length, context); 30 return false; 31 } 32 33 static int32_t 34 raw_read_int(Tuple *tuple) { 35 switch (tuple->length) { 36 case 1: 37 return tuple->value->int8; 38 case 2: 39 return tuple->value->int16; 40 case 4: 41 return tuple->value->int32; 42 default: 43 return 0; 44 } 45 } 46 47 static uint32_t 48 raw_read_uint(Tuple *tuple) { 49 switch (tuple->length) { 50 case 1: 51 return tuple->value->uint8; 52 case 2: 53 return tuple->value->uint16; 54 case 4: 55 return tuple->value->uint32; 56 default: 57 return 0; 58 } 59 } 60 61 int32_t 62 tuple_int(Tuple *tuple) { 63 if (!tuple) return 0; 64 switch (tuple->type) { 65 case TUPLE_INT: 66 if (!check_length(tuple, "integer")) return 0; 67 return raw_read_int(tuple); 68 case TUPLE_UINT: 69 if (!check_length(tuple, "integer")) return 0; 70 uint32_t u = raw_read_uint(tuple); 71 if (u > 2147483647) { 72 APP_LOG(APP_LOG_LEVEL_ERROR, 73 "Integer overflow in signed dictionary entry %" 74 PRIu32, u); 75 return 0; 76 } 77 return u; 78 default: 79 APP_LOG(APP_LOG_LEVEL_ERROR, 80 "Unexpected type %d for integer dictionary entry", 81 (int)tuple->type); 82 return 0; 83 } 84 } 85 86 uint32_t 87 tuple_uint(Tuple *tuple) { 88 if (!tuple) return 0; 89 switch (tuple->type) { 90 case TUPLE_UINT: 91 if (!check_length(tuple, "unsigned")) return 0; 92 return raw_read_uint(tuple); 93 case TUPLE_INT: 94 if (!check_length(tuple, "unsigned")) return 0; 95 int32_t i = raw_read_int(tuple); 96 if (i < 0) { 97 APP_LOG(APP_LOG_LEVEL_ERROR, 98 "Integer underflow in unsigned dictionary entry %" 99 PRIi32, i); 100 return 0; 101 } 102 return i; 103 default: 104 APP_LOG(APP_LOG_LEVEL_ERROR, 105 "Unexpected type %d for unsigned dictionary entry", 106 (int)tuple->type); 107 return 0; 108 } 109 }