static tsf_bool_t read_buffer_impl()

in benchmarks/JetStream2/wasm/TSF/tsf_buffer.c [319:436]


static tsf_bool_t read_buffer_impl(tsf_buffer_t *result,
                                   uint32_t type_code,
                                   tsf_type_in_map_t *enclosing_types,
                                   tsf_reader_t reader,
                                   void *arg,
                                   tsf_limits_t *limits,
                                   length_size_t length_size) {
    uint32_t size;
    
    if (type_code >= tsf_type_in_map_get_num_types(enclosing_types)) {
        tsf_set_error(TSF_E_PARSE_ERROR,
                      "Type code is outside of bounds of type map: "
                      fui32 " is the type code, while the type map "
                      "has a size of " fui32,
                      type_code,
                      tsf_type_in_map_get_num_types(enclosing_types));
        goto error1;
    }
    
    result->type = tsf_type_dup(
        tsf_type_in_map_get_type(enclosing_types, type_code));
    
    if (tsf_type_is_dynamic(result->type)) {
        /* must read type translation table. */
        uint32_t num_types;
        uint32_t index;
        
        result->types = tsf_type_in_map_create();
        if (result->types == NULL) {
            goto error2;
        }
        
        if (!reader(arg, &num_types, sizeof(num_types))) {
            goto error3;
        }
        
        num_types = ntohl(num_types);
        
        tsf_type_in_map_prepare(result->types, num_types);
        
        while (num_types --> 0) {
            if (!reader(arg, &index, sizeof(index))) {
                goto error3;
            }
            
            index = ntohl(index);
            
            if (index >= tsf_type_in_map_get_num_types(enclosing_types)) {
                tsf_set_error(TSF_E_PARSE_ERROR,
                              "Index " fui32 " into enclosing type table "
                              "is outside of bounds; the enclosing table "
                              "has a size of " fui32,
                              index,
                              tsf_type_in_map_get_num_types(enclosing_types));
                goto error3;
            }
            
            if (!tsf_type_in_map_append(
                    result->types,
                    tsf_type_in_map_get_type(enclosing_types, index))) {
                goto error3;
            }
        }
    } else {
        result->types = tsf_type_in_map_get_empty_singleton();
    }

    switch (length_size) {
    case small_length: {
        uint8_t my_size;
        if (!reader(arg, &my_size, sizeof(my_size))) {
            goto error3;
        }
        size = my_size;
        break;
    }
    case large_length: {
        if (!reader(arg, &size, sizeof(size))) {
            goto error3;
        }
        size = ntohl(size);
        break;
    } }
    
    if (size > tsf_limits_max_buf_size(limits)) {
        tsf_set_error(TSF_E_PARSE_ERROR,
                      "Buffer size exceeds limit");
        goto error3;
    }
    
    if (size > result->size) {
        result->data = malloc(size);
        if (result->data == NULL) {
            tsf_set_errno("Could not allocate buffer data.");
            goto error3;
        }
        
        result->keep = tsf_true;
    }
    
    result->size = size;
    
    if (!reader(arg, result->data, result->size)) {
        goto error4;
    }
    
    return tsf_true;

error4:
    free(result->data);
    result->keep = tsf_false;
error3:
    tsf_type_in_map_destroy(result->types);
error2:
    tsf_type_destroy(result->type);
error1:
    return tsf_false;
}