/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include "dataimpl.h" namespace pvxs { namespace { struct FmtDelta { std::ostream& strm; const Value::Fmt& fmt; void field(const std::string& prefix, const Value& val, bool verytop) { if(verytop && !val.isMarked()) return; strm<as(); break; case StoreType::UInteger: strm<<" = "<as(); break; case StoreType::Bool: strm<<" = "<<(store->as() ? "true" : "false"); break; case StoreType::String: strm<<" = \""<as())<<"\""; break; case StoreType::Array: { auto& varr = store->as>(); if(varr.original_type()!=ArrayType::Value) { strm<<" = "<(); std::string cprefix(prefix); cprefix+="->"; if(val.type()==TypeCode::Union) { auto desc = Value::Helper::desc(val); auto udesc = Value::Helper::desc(uval); for(auto idx : range(desc->members.size())) { if(udesc == &desc->members[idx]) { cprefix+=desc->miter[idx].first; break; } } } top(cprefix, uval, false); } break; case TypeCode::StructA: case TypeCode::UnionA: case TypeCode::AnyA: { auto rawval = val.as>(); if(rawval.original_type()==ArrayType::Null) { } else if(rawval.original_type()==ArrayType::Value) { auto aval = rawval.castTo(); for(auto idx : range(aval.size())) { std::ostringstream strm; strm<code; if(!desc->id.empty()) strm<<" \""<id<<"\""; if(!member.empty() && desc->code!=TypeCode::Struct) strm<<" "<code) { case StoreType::Null: if(desc->code==TypeCode::Struct) { strm<<" {\n"; for(auto& pair : desc->miter) { auto cdesc = desc + pair.second; Indented I(strm); top(pair.first, cdesc, store + pair.second); } strm<as()); } strm<<"\"\n"; break; case StoreType::Compound: { auto& fld = store->as(); if(fld.valid() && desc->code==TypeCode::Union) { for(auto& pair : desc->miter) { if(&desc->members[pair.second] == Value::Helper::desc(fld)) { strm<<"."<as>(); if(!fmt._showValue) { strm<<"\n"; } else if(varr.original_type()!=ArrayType::Value) { strm<<" = "<(); strm<<" [\n"; for(auto& val : arr) { Indented I(strm); top(std::string(), Value::Helper::desc(val), Value::Helper::store_ptr(val)); } strm<code)<<"\n"; break; } } }; } // namespace std::ostream& operator<<(std::ostream& strm, const Value::Fmt& fmt) { switch (fmt._format) { case Value::Fmt::Tree: FmtTree{strm, fmt}.top("", Value::Helper::desc(*fmt.top), Value::Helper::store_ptr(*fmt.top)); break; case Value::Fmt::Delta: FmtDelta{strm, fmt}.top("", *fmt.top, true); break; default: strm<<"\n"; } return strm; } }