diff --git a/ChangeLog b/ChangeLog index 01be3cd0a..6c8a5aca2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-12 Alexandre Duret-Lutz + + More interfaces to the int array compression routines. + + * src/misc/intvcomp.cc, src/misc/intvcomp.cc: Add interfaces to + compress vector to vector. + * src/tgbatest/intvcomp.cc: Test them. + * src/sanity/style.test: Refine check to avoid a spurious report. + 2011-04-11 Alexandre Duret-Lutz * iface/dve2/dve2.cc: Typo when handling dead==true. diff --git a/src/misc/intvcomp.cc b/src/misc/intvcomp.cc index e89cef1be..35aec14ec 100644 --- a/src/misc/intvcomp.cc +++ b/src/misc/intvcomp.cc @@ -232,6 +232,50 @@ namespace spot std::vector* result_; }; + class int_vector_vector_compression: + public stream_compression_base + { + public: + int_vector_vector_compression(const std::vector& input, + std::vector& output) + : input_(input), pos_(input.begin()), end_(input.end()), output_(output) + { + } + + void push_data(unsigned int i) + { + output_.push_back(i); + } + + bool have_data() const + { + return pos_ < end_; + } + + unsigned int next_data() + { + return static_cast(*pos_++); + } + + bool skip_if(unsigned int val) + { + if (!have_data()) + return false; + + if (static_cast(*pos_) != val) + return false; + + ++pos_; + return true; + } + + protected: + const std::vector& input_; + std::vector::const_iterator pos_; + std::vector::const_iterator end_; + std::vector& output_; + }; + class int_array_array_compression: public stream_compression_base { @@ -283,6 +327,14 @@ namespace spot }; } + void + int_vector_vector_compress(const std::vector& input, + std::vector& output) + { + int_vector_vector_compression c(input, output); + c.run(); + } + const std::vector* int_array_vector_compress(const int* array, size_t n) { @@ -456,6 +508,57 @@ namespace spot unsigned int buffer_mask_; }; + class int_vector_vector_decompression: + public stream_decompression_base + { + public: + int_vector_vector_decompression(const std::vector& array, + std::vector& res, size_t size) + : prev_(0), array_(array), + pos_(array.begin()), end_(array.end()), + result_(res), size_(size) + { + result_.reserve(size); + } + + bool complete() const + { + return size_ == 0; + } + + void push_data(int i) + { + prev_ = i; + result_.push_back(i); + --size_; + } + + void repeat(unsigned int i) + { + size_ -= i; + while (i--) + result_.push_back(prev_); + } + + bool have_comp_data() const + { + return pos_ != end_; + } + + unsigned int next_comp_data() + { + return *pos_++; + } + + protected: + int prev_; + const std::vector& array_; + std::vector::const_iterator pos_; + std::vector::const_iterator end_; + std::vector& result_; + size_t size_; + }; + class int_vector_array_decompression: public stream_decompression_base { @@ -559,6 +662,14 @@ namespace spot } + void + int_vector_vector_decompress(const std::vector& input, + std::vector& output, size_t size) + { + int_vector_vector_decompression c(input, output, size); + c.run(); + } + void int_vector_array_decompress(const std::vector* array, int* res, size_t size) diff --git a/src/misc/intvcomp.hh b/src/misc/intvcomp.hh index 4a2d59a53..335ec6af8 100644 --- a/src/misc/intvcomp.hh +++ b/src/misc/intvcomp.hh @@ -28,11 +28,24 @@ namespace spot /// \addtogroup misc_tools /// @{ + /// Compress an int vector into a vector of unsigned int. + void + int_vector_vector_compress(const std::vector& input, + std::vector& output); + + /// \brief Uncompress a vector of unsigned int into a vector of + /// size \a size. + /// + /// \a size must be the exact expected size of uncompressed array. + void + int_vector_vector_decompress(const std::vector& array, + std::vector& output, size_t size); + /// Compress an int array if size \a n into a vector of unsigned int. const std::vector* int_array_vector_compress(const int* array, size_t n); - /// \brief Uncompress a vector of unsigned int into an int array if + /// \brief Uncompress a vector of unsigned int into an int array of /// size \a size. /// /// \a size must be the exact expected size of uncompressed array. diff --git a/src/sanity/style.test b/src/sanity/style.test index 7c87a921f..5d3bb2c13 100755 --- a/src/sanity/style.test +++ b/src/sanity/style.test @@ -165,7 +165,7 @@ for dir in "${INCDIR-..}" "${INCDIR-..}"/../iface; do egrep '(->|[.])size\(\) [=!]= 0|![a-zA-Z0-9_]*(->|[.])size\(\)|(if |while |assert)\([a-zA-Z0-9_]*(->|[.])size\(\)\)' $tmp && diag 'Prefer empty() to check emptiness.' - egrep '^[^=]*([+][+]|--);' $tmp && + egrep '^[^=*]*([+][+]|--);' $tmp && diag 'Take good habits: use ++i instead of i++ when you have the choice.' grep '[^a-zA-Z0-9_](\*[a-zA-Z0-9_]*)\.' $tmp && diff --git a/src/tgbatest/intvcomp.cc b/src/tgbatest/intvcomp.cc index 8c5cd6f1b..2aa507c4b 100644 --- a/src/tgbatest/intvcomp.cc +++ b/src/tgbatest/intvcomp.cc @@ -22,6 +22,54 @@ #include "misc/intvcomp.hh" #include +int check_vv(int* data, int size, unsigned expected = 0) +{ + + std::vector input; + input.reserve(size); + for (int i = 0; i < size; ++i) + input.push_back(data[i]); + + std::vector output; + spot::int_vector_vector_compress(input, output); + + std::cout << "WC[" << output.size() << "] "; + for (size_t i = 0; i < output.size(); ++i) + std::cout << output[i] << " "; + std::cout << std::endl; + + std::vector decomp; + spot::int_vector_vector_decompress(output, decomp, size); + + std::cout << "WD[" << decomp.size() << "] "; + for (size_t i = 0; i < decomp.size(); ++i) + std::cout << decomp[i] << " "; + std::cout << std::endl; + + int res = (decomp != input); + + if (res) + { + std::cout << "*** cmp error *** " << std::endl; + std::cout << "WE[" << size << "] "; + for (int i = 0; i < size; ++i) + std::cout << data[i] << " "; + std::cout << std::endl; + } + + if (expected && (output.size() * sizeof(int) != expected)) + { + std::cout << "*** size error *** (expected " + << expected << " bytes, got " << output.size() * sizeof(int) + << " bytes)" << std::endl; + res = 1; + } + + std::cout << std::endl; + + return !!res; +} + int check_av(int* data, int size, unsigned expected = 0) { const std::vector* v = @@ -113,7 +161,10 @@ int check_aa(int* data, int size, unsigned expected = 0) int check(int* comp, int size, unsigned expected = 0) { - return check_av(comp, size, expected) + check_aa(comp, size, expected); + return + check_vv(comp, size, expected) + + check_av(comp, size, expected) + + check_aa(comp, size, expected); } int main()