diff --git a/src/clientmon.cpp b/src/clientmon.cpp index bdcd4e2..0c1f9b0 100644 --- a/src/clientmon.cpp +++ b/src/clientmon.cpp @@ -547,47 +547,7 @@ void Connection::handle_MONITOR() } from_wire_valid(M, rxRegistry, data); - /* co-iterate data and prototype. - * copy marked from data -> prototype - * copy unmarked from prototype -> data - */ - { - auto desc = Value::Helper::desc(info->prototype); - auto delta = Value::Helper::store_ptr(data); - auto complete = Value::Helper::store_ptr(info->prototype); - auto N = desc->size(); - for(size_t i=0u; i < N; i++, delta++, complete++) - { - const auto src = delta->valid ? delta : complete; - auto dst = delta->valid ? complete : delta; - - switch(delta->code) { - case StoreType::Null: - break; - case StoreType::Bool: - case StoreType::UInteger: - case StoreType::Integer: - case StoreType::Real: - memcpy(&dst->store, &src->store, sizeof(src->store)); - break; - case StoreType::String: - dst->as() = src->as(); - break; - case StoreType::Array: - dst->as>() = src->as>(); - break; - case StoreType::Compound: - { - std::shared_ptr sstore(Value::Helper::store(data), - src); - auto& dfld(dst->as()); - Value::Helper::set_desc(dfld, &desc[i]); - Value::Helper::store(dfld) = std::move(sstore); - } - break; - } - } - } + cache_sync(info->prototype, data); BitMask overrun; from_wire(M, overrun); diff --git a/src/data.cpp b/src/data.cpp index e640197..a3bc571 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -1184,6 +1184,52 @@ Value::_Iterator::operator++() noexcept return *this; } +void cache_sync(Value& cache, Value& dlt) +{ + if(!cache.equalType(dlt)) + throw std::logic_error(SB()<<__func__<<" requires matching types"); + + /* co-iterate data and prototype. + * copy marked from data -> prototype + * copy unmarked from prototype -> data + */ + auto desc = Value::Helper::desc(cache); + auto delta = Value::Helper::store_ptr(dlt); + auto complete = Value::Helper::store_ptr(cache); + auto N = desc->size(); + for(size_t i=0u; i < N; i++, delta++, complete++) + { + const auto src = delta->valid ? delta : complete; + auto dst = delta->valid ? complete : delta; + + switch(delta->code) { + case StoreType::Null: + break; + case StoreType::Bool: + case StoreType::UInteger: + case StoreType::Integer: + case StoreType::Real: + memcpy(&dst->store, &src->store, sizeof(src->store)); + break; + case StoreType::String: + dst->as() = src->as(); + break; + case StoreType::Array: + dst->as>() = src->as>(); + break; + case StoreType::Compound: + { + std::shared_ptr sstore(Value::Helper::store(dlt), + src); + auto& dfld(dst->as()); + Value::Helper::set_desc(dfld, &desc[i]); + Value::Helper::store(dfld) = std::move(sstore); + } + break; + } + } +} + namespace impl { void FieldStorage::init(StoreType code) diff --git a/src/dataimpl.h b/src/dataimpl.h index 1e6c71c..98c7fd7 100644 --- a/src/dataimpl.h +++ b/src/dataimpl.h @@ -41,6 +41,14 @@ struct Value::Helper { static std::shared_ptr type(const Value& v); }; +/* Refresh cache from delta, and populate delta with previous. + * Requires matching types. + * + * copy marked from delta -> cache + * copy unmarked from cache -> delta + */ +void cache_sync(Value& cache, Value& delta); + namespace impl { struct Buffer;