From e8d3d38fea3fa2268c17ea8670a448a178363faf Mon Sep 17 00:00:00 2001 From: David Roazen Date: Wed, 1 Oct 2014 12:06:42 -0400 Subject: [PATCH] Fix bug in validation of vector lengths when setting individual fields Previous validation routine would incorrectly allow nested vectors whose first dimension was greater than but divisible by the number of samples. Now validation of vector is separated from validation of flattened vectors. --- gamgee/variant_builder.cpp | 17 +++++++++++++---- gamgee/variant_builder.h | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/gamgee/variant_builder.cpp b/gamgee/variant_builder.cpp index f4bbc0578..27122974a 100644 --- a/gamgee/variant_builder.cpp +++ b/gamgee/variant_builder.cpp @@ -471,7 +471,7 @@ VariantBuilder& VariantBuilder::bulk_set_individual_field(const FIELD_ID_TYPE& f const auto field_idx = field_index(field_id); if ( m_enable_validation ) { validate_individual_field(field_idx, provided_type); - validate_multi_sample_indiv_vector_length(field_values.size()); + validate_multi_sample_vector_length(field_values); } // Need to use std::forward() here so that we can handle both the move and the copy use cases fields_of_type[m_indiv_field_lookup_table[field_idx]].set_entire_field(std::forward(field_values)); @@ -569,12 +569,21 @@ void VariantBuilder::validate_individual_field_existence(const int32_t field_ind } } -inline void VariantBuilder::validate_multi_sample_indiv_vector_length(const uint32_t length) const { - if ( length == 0 || length % uint32_t(bcf_hdr_nsamples(m_header.get())) != 0 ) { - throw invalid_argument(string{"Number of elements in vector for individual field ("} + to_string(length) + ") not divisible by number of samples (" + to_string(uint32_t(bcf_hdr_nsamples(m_header.get()))) + ")"); +template +inline void VariantBuilder::validate_multi_sample_vector_length(const std::vector>& vec) const { + const auto num_samples = uint32_t(bcf_hdr_nsamples(m_header.get())); + if ( vec.size() != num_samples ) { + throw invalid_argument(string{"Number of elements in vector of vectors for individual field ("} + to_string(vec.size()) + ") not equal to the number of samples (" + to_string(num_samples) + ")"); } } +template +inline void VariantBuilder::validate_multi_sample_vector_length(const std::vector& vec) const { + const auto num_samples = uint32_t(bcf_hdr_nsamples(m_header.get())); + if ( vec.size() < num_samples || vec.size() % num_samples != 0 ) { + throw invalid_argument(string{"Number of elements in flattened vector for individual field ("} + to_string(vec.size()) + ") not divisible by number of samples (" + to_string(num_samples) + ")"); + } +} void VariantBuilder::pre_build_validation() const { if ( (m_starting_variant_body == nullptr && (m_ref_allele.missing() || m_ref_allele.encoded_length() == 0)) || diff --git a/gamgee/variant_builder.h b/gamgee/variant_builder.h index 2af0db46b..86c7dffc3 100644 --- a/gamgee/variant_builder.h +++ b/gamgee/variant_builder.h @@ -188,7 +188,8 @@ class VariantBuilder { void validate_individual_field(const int32_t field_index, const uint32_t provided_type) const; void validate_individual_field(const int32_t field_index, const int32_t sample_index, const uint32_t provided_type) const; inline void validate_individual_field_existence(const int32_t field_index) const; - inline void validate_multi_sample_indiv_vector_length(const uint32_t length) const; + template inline void validate_multi_sample_vector_length(const std::vector>& vec) const; + template inline void validate_multi_sample_vector_length(const std::vector& vec) const; void pre_build_validation() const; void post_build_validation(const std::shared_ptr& new_variant_body) const;