diff --git a/include/bmi_lgar.hxx b/include/bmi_lgar.hxx index 91a1cbb..d4a131d 100644 --- a/include/bmi_lgar.hxx +++ b/include/bmi_lgar.hxx @@ -184,7 +184,7 @@ private: void serialize_wetting_front_list(Archive &ar, wetting_front **head, int &count); void new_serialized(); - void load_serialized(const char* data); + void load_serialized(char* data); void free_serialized(); }; diff --git a/include/vecbuf.hpp b/include/vecbuf.hpp index 6db982c..a20bc70 100644 --- a/include/vecbuf.hpp +++ b/include/vecbuf.hpp @@ -28,6 +28,9 @@ class vecbuf : public std::basic_streambuf { // Forwarder for std::vector::clear() constexpr void clear() { vector_.clear(); } + // Forwarder for std::vector::resize(size) + constexpr void resize(size_type size) { vector_.resize(size); } + // Forwarder for std::vector::reserve constexpr void reserve(size_type capacity) { vector_.reserve(capacity); setp_from_vector(); } @@ -35,7 +38,7 @@ class vecbuf : public std::basic_streambuf { constexpr void reserve_additional(size_type additional_capacity) { reserve(size() + additional_capacity); } // Forwarder for std::vector::data - constexpr const value_type* data() const { return vector_.data(); } + constexpr value_type* data() { return vector_.data(); } // Forwarder for std::vector::size constexpr size_type size() const { return vector_.size(); } @@ -112,4 +115,11 @@ class vecbuf : public std::basic_streambuf { }; +class membuf : public std::streambuf { +public: + membuf(char *begin, size_t size) { + this->setg(begin, begin, begin + size); + } +}; + #endif diff --git a/src/bmi_lgar.cxx b/src/bmi_lgar.cxx index a580b2f..4b252bd 100644 --- a/src/bmi_lgar.cxx +++ b/src/bmi_lgar.cxx @@ -773,6 +773,7 @@ GetVarGrid(std::string name) || name.compare("groundwater_to_stream_recharge") == 0 || name.compare("mass_balance") == 0 || name.compare(NWM_PONDED_DEPTH_OUT_VAR) == 0 + || name.compare("reset_time") == 0 ) // double return 1; else if ( @@ -1086,6 +1087,11 @@ SetValue (std::string name, void *src) } else if (name.compare("serialization_create") == 0) { this->new_serialized(); return; + } else if (name.compare("reset_time") == 0) { + // time_s and timesteps seems to be used exclusively for reporting current time + this->state->lgar_bmi_params.time_s = this->GetStartTime(); + this->state->lgar_bmi_params.timesteps = 0; + return; } void * dest = NULL; dest = this->GetValuePtr(name); @@ -1430,11 +1436,15 @@ void BmiLGAR::serialize_wetting_front_list(Archive &ar, wetting_front **head, in } void BmiLGAR::new_serialized() { - this->m_serialized.clear(); + // resize with reserved space for storing size + this->m_serialized.resize(sizeof(uint64_t)); boost::archive::binary_oarchive archive(this->m_serialized); try { archive << (*this); this->m_serialized_length = this->m_serialized.size(); + // get serialized size without header and copy size to the beginning of the buffer + uint64_t serialized_size = this->m_serialized_length - sizeof(uint64_t); + memcpy(this->m_serialized.data(), &serialized_size, sizeof(uint64_t)); } catch (const std::exception &e) { Logger::Log(LogLevel::SEVERE, "Serializing LASAM encountered an error: %s", e.what()); this->free_serialized(); @@ -1442,8 +1452,12 @@ void BmiLGAR::new_serialized() { } } -void BmiLGAR::load_serialized(const char* data) { - std::stringstream stream(data); +void BmiLGAR::load_serialized(char* data) { + // copy size from the start of data + uint64_t size; + memcpy(&size, data, sizeof(uint64_t)); + // create stream from everything past the size header + membuf stream(data + sizeof(uint64_t), size); boost::archive::binary_iarchive archive(stream); try { archive >> (*this);