aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-01 17:43:20 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-01 18:30:27 +0100
commitb1ccdd2e6af952961f50b1d3f9da3dc192d4c8cc (patch)
treed31883ed8ca6ee18d6a4ff31cfb1d41b615f5c8a
parentc94a500a0b3e98e2d75bdfe667fe85949a1f8c27 (diff)
downloadpaludis-b1ccdd2e6af952961f50b1d3f9da3dc192d4c8cc.tar.gz
paludis-b1ccdd2e6af952961f50b1d3f9da3dc192d4c8cc.tar.xz
serialise
-rw-r--r--paludis/resolver/Makefile.am2
-rw-r--r--paludis/resolver/arrow.cc21
-rw-r--r--paludis/resolver/arrow.hh6
-rw-r--r--paludis/resolver/constraint.cc80
-rw-r--r--paludis/resolver/constraint.hh11
-rw-r--r--paludis/resolver/decision.cc31
-rw-r--r--paludis/resolver/decision.hh6
-rw-r--r--paludis/resolver/destinations.cc44
-rw-r--r--paludis/resolver/destinations.hh11
-rw-r--r--paludis/resolver/qpn_s.cc24
-rw-r--r--paludis/resolver/qpn_s.hh6
-rw-r--r--paludis/resolver/reason.cc67
-rw-r--r--paludis/resolver/reason.hh14
-rw-r--r--paludis/resolver/resolution-fwd.hh1
-rw-r--r--paludis/resolver/resolution.cc36
-rw-r--r--paludis/resolver/resolution.hh5
-rw-r--r--paludis/resolver/resolutions-fwd.hh3
-rw-r--r--paludis/resolver/resolutions.cc26
-rw-r--r--paludis/resolver/resolutions.hh4
-rw-r--r--paludis/resolver/sanitised_dependencies.cc50
-rw-r--r--paludis/resolver/sanitised_dependencies.hh13
-rw-r--r--paludis/resolver/serialise-fwd.hh34
-rw-r--r--paludis/resolver/serialise-impl.hh229
-rw-r--r--paludis/resolver/serialise.cc340
-rw-r--r--paludis/resolver/serialise.hh158
-rw-r--r--paludis/resolver/use_installed.se2
-rw-r--r--src/clients/cave/cmd_resolve.cc11
-rw-r--r--src/clients/cave/cmd_resolve_display_resolution.cc4
-rw-r--r--src/clients/cave/cmd_resolve_display_resolution.hh4
29 files changed, 1234 insertions, 9 deletions
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index f820bad..62f2333 100644
--- a/paludis/resolver/Makefile.am
+++ b/paludis/resolver/Makefile.am
@@ -22,6 +22,7 @@ noinst_HEADERS = \
resolver.hh resolver-fwd.hh \
resolver_functions.hh resolver_functions-fwd.hh \
sanitised_dependencies.hh sanitised_dependencies-fwd.hh \
+ serialise.hh serialise-fwd.hh serialise-impl.hh \
suggest_restart.hh suggest_restart-fwd.hh \
use_installed.hh use_installed-fwd.hh use_installed-se.hh
@@ -36,6 +37,7 @@ libpaludisresolver_a_SOURCES = \
resolutions.cc \
resolver.cc \
sanitised_dependencies.cc \
+ serialise.cc \
suggest_restart.cc \
use_installed.cc
diff --git a/paludis/resolver/arrow.cc b/paludis/resolver/arrow.cc
index 5b745cd..d8f58ab 100644
--- a/paludis/resolver/arrow.cc
+++ b/paludis/resolver/arrow.cc
@@ -18,8 +18,10 @@
*/
#include <paludis/resolver/arrow.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/sequence-impl.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/make_named_values.hh>
using namespace paludis;
using namespace paludis::resolver;
@@ -34,6 +36,25 @@ paludis::resolver::operator<< (std::ostream & s, const Arrow & a)
return s;
}
+void
+Arrow::serialise(Serialiser & s) const
+{
+ s.object("Arrow")
+ .member(SerialiserFlags<>(), "ignorable_pass", ignorable_pass())
+ .member(SerialiserFlags<>(), "to_qpn_s", to_qpn_s())
+ ;
+}
+
+const std::tr1::shared_ptr<Arrow>
+Arrow::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Arrow");
+ return make_shared_ptr(new Arrow(make_named_values<Arrow>(
+ value_for<n::ignorable_pass>(v.member<bool>("ignorable_pass")),
+ value_for<n::to_qpn_s>(v.member<QPN_S>("to_qpn_s"))
+ )));
+}
+
template class Sequence<std::tr1::shared_ptr<Arrow> >;
template class WrappedForwardIterator<ArrowSequence::ConstIteratorTag, const std::tr1::shared_ptr<Arrow> >;
diff --git a/paludis/resolver/arrow.hh b/paludis/resolver/arrow.hh
index 7798d03..bbdb930 100644
--- a/paludis/resolver/arrow.hh
+++ b/paludis/resolver/arrow.hh
@@ -22,6 +22,7 @@
#include <paludis/resolver/arrow-fwd.hh>
#include <paludis/resolver/qpn_s.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/named_value.hh>
namespace paludis
@@ -38,6 +39,11 @@ namespace paludis
{
NamedValue<n::ignorable_pass, int> ignorable_pass;
NamedValue<n::to_qpn_s, QPN_S> to_qpn_s;
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Arrow> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/constraint.cc b/paludis/resolver/constraint.cc
index cb7bd59..e423427 100644
--- a/paludis/resolver/constraint.cc
+++ b/paludis/resolver/constraint.cc
@@ -19,9 +19,12 @@
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/reason.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/sequence-impl.hh>
+#include <paludis/util/make_named_values.hh>
#include <sstream>
#include <list>
@@ -52,7 +55,7 @@ namespace paludis
UseInstalled strictest_use_installed;
bool nothing_is_fine_too;
bool to_destination_slash;
- std::list<std::tr1::shared_ptr<const Constraint> > constraints;
+ Sequence<std::tr1::shared_ptr<const Constraint> > constraints;
Implementation() :
strictest_use_installed(ui_if_possible),
@@ -117,6 +120,81 @@ Constraints::to_destination_slash() const
return _imp->to_destination_slash;
}
+void
+Constraints::serialise(Serialiser & s) const
+{
+ s.object("Constraints")
+ .member(SerialiserFlags<serialise::container>(), "items", _imp->constraints)
+ ;
+}
+
+const std::tr1::shared_ptr<Constraints>
+Constraints::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Constraints");
+ Deserialisator vv(*v.find_remove_member("items"), "c");
+ std::tr1::shared_ptr<Constraints> result(new Constraints);
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->add(vv.member<std::tr1::shared_ptr<Constraint> >(stringify(n)));
+ return result;
+}
+
+void
+Constraint::serialise(Serialiser & s) const
+{
+ s.object("Constraint")
+ .member(SerialiserFlags<>(), "nothing_is_fine_too", nothing_is_fine_too())
+ .member(SerialiserFlags<serialise::might_be_null>(), "reason", reason())
+ .member(SerialiserFlags<>(), "spec", spec())
+ .member(SerialiserFlags<>(), "to_destination_slash", to_destination_slash())
+ .member(SerialiserFlags<>(), "use_installed", stringify(use_installed()))
+ ;
+}
+
+namespace
+{
+ struct IDFinder
+ {
+ const std::tr1::shared_ptr<const PackageID> visit(const DependencyReason & r) const
+ {
+ return r.from_id();
+ }
+
+ const std::tr1::shared_ptr<const PackageID> visit(const SetReason &) const
+ {
+ return make_null_shared_ptr();
+ }
+
+ const std::tr1::shared_ptr<const PackageID> visit(const PresetReason &) const
+ {
+ return make_null_shared_ptr();
+ }
+
+ const std::tr1::shared_ptr<const PackageID> visit(const TargetReason &) const
+ {
+ return make_null_shared_ptr();
+ }
+ };
+}
+
+const std::tr1::shared_ptr<Constraint>
+Constraint::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Constraint");
+
+ const std::tr1::shared_ptr<Reason> reason(v.member<std::tr1::shared_ptr<Reason> >("reason"));
+ IDFinder id_finder;
+
+ return make_shared_ptr(new Constraint(make_named_values<Constraint>(
+ value_for<n::nothing_is_fine_too>(v.member<bool>("nothing_is_fine_too")),
+ value_for<n::reason>(reason),
+ value_for<n::spec>(PackageOrBlockDepSpec::deserialise(*v.find_remove_member("spec"),
+ reason->accept_returning<std::tr1::shared_ptr<const PackageID> >(id_finder))),
+ value_for<n::to_destination_slash>(v.member<bool>("to_destination_slash")),
+ value_for<n::use_installed>(destringify<UseInstalled>(v.member<std::string>("use_installed")))
+ )));
+}
+
template class PrivateImplementationPattern<Constraints>;
template class WrappedForwardIterator<Constraints::ConstIteratorTag, const std::tr1::shared_ptr<const Constraint> >;
diff --git a/paludis/resolver/constraint.hh b/paludis/resolver/constraint.hh
index 7b6fbdb..2c8c760 100644
--- a/paludis/resolver/constraint.hh
+++ b/paludis/resolver/constraint.hh
@@ -24,6 +24,7 @@
#include <paludis/resolver/reason-fwd.hh>
#include <paludis/resolver/use_installed-fwd.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/named_value.hh>
#include <paludis/dep_spec.hh>
#include <tr1/memory>
@@ -48,6 +49,11 @@ namespace paludis
NamedValue<n::spec, PackageOrBlockDepSpec> spec;
NamedValue<n::to_destination_slash, bool> to_destination_slash;
NamedValue<n::use_installed, UseInstalled> use_installed;
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Constraint> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
class PALUDIS_VISIBLE Constraints :
@@ -69,6 +75,11 @@ namespace paludis
ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
bool empty() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Constraints> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/resolver/decision.cc b/paludis/resolver/decision.cc
index 3d3e675..e00ed96 100644
--- a/paludis/resolver/decision.cc
+++ b/paludis/resolver/decision.cc
@@ -18,6 +18,8 @@
*/
#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/serialise-impl.hh>
+#include <paludis/util/make_named_values.hh>
#include <sstream>
using namespace paludis;
@@ -52,3 +54,32 @@ paludis::resolver::operator<< (std::ostream & s, const Decision & d)
return s;
}
+void
+Decision::serialise(Serialiser & s) const
+{
+ s.object("Decision")
+ .member(SerialiserFlags<serialise::might_be_null>(), "if_package_id", if_package_id())
+ .member(SerialiserFlags<>(), "is_best", is_best())
+ .member(SerialiserFlags<>(), "is_installed", is_installed())
+ .member(SerialiserFlags<>(), "is_nothing", is_nothing())
+ .member(SerialiserFlags<>(), "is_same", is_same())
+ .member(SerialiserFlags<>(), "is_same_version", is_same_version())
+ .member(SerialiserFlags<>(), "is_transient", is_transient())
+ ;
+}
+
+const std::tr1::shared_ptr<Decision>
+Decision::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Decision");
+ return make_shared_ptr(new Decision(make_named_values<Decision>(
+ value_for<n::if_package_id>(v.member<std::tr1::shared_ptr<const PackageID> >("if_package_id")),
+ value_for<n::is_best>(v.member<bool>("is_best")),
+ value_for<n::is_installed>(v.member<bool>("is_installed")),
+ value_for<n::is_nothing>(v.member<bool>("is_nothing")),
+ value_for<n::is_same>(v.member<bool>("is_same")),
+ value_for<n::is_same_version>(v.member<bool>("is_same_version")),
+ value_for<n::is_transient>(v.member<bool>("is_transient"))
+ )));
+}
+
diff --git a/paludis/resolver/decision.hh b/paludis/resolver/decision.hh
index 9bfac0f..a0c6728 100644
--- a/paludis/resolver/decision.hh
+++ b/paludis/resolver/decision.hh
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_DECISION_HH 1
#include <paludis/resolver/decision-fwd.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/named_value.hh>
#include <paludis/package_id.hh>
@@ -48,6 +49,11 @@ namespace paludis
NamedValue<n::is_same, bool> is_same;
NamedValue<n::is_same_version, bool> is_same_version;
NamedValue<n::is_transient, bool> is_transient;
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Decision> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/destinations.cc b/paludis/resolver/destinations.cc
index 694561c..26c086a 100644
--- a/paludis/resolver/destinations.cc
+++ b/paludis/resolver/destinations.cc
@@ -18,10 +18,12 @@
*/
#include <paludis/resolver/destinations.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/join.hh>
+#include <paludis/util/make_named_values.hh>
#include <paludis/package_id.hh>
#include <ostream>
#include <sstream>
@@ -56,3 +58,45 @@ paludis::resolver::operator<< (std::ostream & s, const Destinations & d)
return s;
}
+void
+Destinations::serialise(Serialiser & s) const
+{
+ s.object("Destinations")
+ .member(SerialiserFlags<serialise::might_be_null>(), "slash", slash())
+ ;
+}
+
+void
+Destination::serialise(Serialiser & s) const
+{
+ s.object("Destination")
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "replacing", replacing())
+ .member(SerialiserFlags<>(), "repository", stringify(repository()))
+ ;
+}
+
+const std::tr1::shared_ptr<Destinations>
+Destinations::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Destinations");
+ return make_shared_ptr(new Destinations(make_named_values<Destinations>(
+ value_for<n::slash>(v.member<std::tr1::shared_ptr<Destination> >("slash"))
+ )));
+}
+
+const std::tr1::shared_ptr<Destination>
+Destination::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Destination");
+
+ std::tr1::shared_ptr<PackageIDSequence> replacing(new PackageIDSequence);
+ Deserialisator vv(*v.find_remove_member("replacing"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ replacing->push_back(vv.member<std::tr1::shared_ptr<const PackageID> >(stringify(n)));
+
+ return make_shared_ptr(new Destination(make_named_values<Destination>(
+ value_for<n::replacing>(replacing),
+ value_for<n::repository>(RepositoryName(v.member<std::string>("repository")))
+ )));
+}
+
diff --git a/paludis/resolver/destinations.hh b/paludis/resolver/destinations.hh
index e3cb66d..8c327dc 100644
--- a/paludis/resolver/destinations.hh
+++ b/paludis/resolver/destinations.hh
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_DESTINATIONS_HH 1
#include <paludis/resolver/destinations-fwd.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/named_value.hh>
#include <paludis/name.hh>
#include <paludis/package_id-fwd.hh>
@@ -41,11 +42,21 @@ namespace paludis
{
NamedValue<n::replacing, std::tr1::shared_ptr<const PackageIDSequence> > replacing;
NamedValue<n::repository, RepositoryName> repository;
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Destination> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
struct Destinations
{
NamedValue<n::slash, std::tr1::shared_ptr<Destination> > slash;
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Destinations> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/qpn_s.cc b/paludis/resolver/qpn_s.cc
index 47746f3..2f5b2ec 100644
--- a/paludis/resolver/qpn_s.cc
+++ b/paludis/resolver/qpn_s.cc
@@ -18,9 +18,12 @@
*/
#include <paludis/resolver/qpn_s.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/sequence-impl.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/make_named_values.hh>
#include <paludis/filter.hh>
#include <paludis/dep_spec.hh>
#include <paludis/package_id.hh>
@@ -128,7 +131,7 @@ paludis::resolver::operator<< (std::ostream & s, const QPN_S & q)
if (q.slot_name_or_null())
ss << ":" << *q.slot_name_or_null();
else
- ss << ":(no slot)";
+ ss << " (no slot)";
s << ss.str();
return s;
@@ -154,6 +157,25 @@ QPN_S::operator= (const QPN_S & other)
return *this;
}
+void
+QPN_S::serialise(Serialiser & s) const
+{
+ s.object("QPN_S")
+ .member(SerialiserFlags<>(), "package", stringify(package()))
+ .member(SerialiserFlags<>(), "slot", slot_name_or_null() ? stringify(*slot_name_or_null()) : "")
+ ;
+}
+
+QPN_S
+QPN_S::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "QPN_S");
+ std::string slot_str(v.member<std::string>("slot"));
+ return QPN_S(
+ QualifiedPackageName(v.member<std::string>("package")),
+ ! slot_str.empty() ? make_shared_ptr(new SlotName(slot_str)) : make_null_shared_ptr());
+}
+
template class PrivateImplementationPattern<QPN_S>;
template class WrappedForwardIterator<QPN_S_Sequence::ConstIteratorTag, const QPN_S>;
diff --git a/paludis/resolver/qpn_s.hh b/paludis/resolver/qpn_s.hh
index 2872bbe..4917b62 100644
--- a/paludis/resolver/qpn_s.hh
+++ b/paludis/resolver/qpn_s.hh
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_QPN_S_HH 1
#include <paludis/resolver/qpn_s-fwd.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/named_value.hh>
#include <paludis/util/attributes.hh>
#include <paludis/util/private_implementation_pattern.hh>
@@ -58,6 +59,11 @@ namespace paludis
bool operator< (const QPN_S & other) const PALUDIS_ATTRIBUTE((warn_unused_result));
bool operator== (const QPN_S & other) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ void serialise(Serialiser &) const;
+
+ static QPN_S deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/resolver/reason.cc b/paludis/resolver/reason.cc
index 76b4e6b..382e6e1 100644
--- a/paludis/resolver/reason.cc
+++ b/paludis/resolver/reason.cc
@@ -20,6 +20,7 @@
#include <paludis/resolver/reason.hh>
#include <paludis/resolver/qpn_s.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
@@ -43,6 +44,13 @@ TargetReason::as_string() const
return "Target()";
}
+void
+TargetReason::serialise(Serialiser & s) const
+{
+ s.object("TargetReason")
+ ;
+}
+
namespace paludis
{
template <>
@@ -87,12 +95,28 @@ DependencyReason::as_string() const
return "Dependency(package: " + stringify(*_imp->from_id) + " dep: " + stringify(_imp->dep) + ")";
}
+void
+DependencyReason::serialise(Serialiser & s) const
+{
+ s.object("DependencyReason")
+ .member(SerialiserFlags<serialise::might_be_null>(), "from_id", from_id())
+ .member(SerialiserFlags<>(), "sanitised_dependency", sanitised_dependency())
+ ;
+}
+
std::string
PresetReason::as_string() const
{
return "Preset()";
}
+void
+PresetReason::serialise(Serialiser & s) const
+{
+ s.object("PresetReason")
+ ;
+}
+
namespace paludis
{
template <>
@@ -136,6 +160,49 @@ SetReason::as_string() const
return "Set(set: " + stringify(_imp->set_name) + " because: " + stringify(*_imp->reason_for_set) + ")";
}
+void
+SetReason::serialise(Serialiser & s) const
+{
+ s.object("SetReason")
+ .member(SerialiserFlags<serialise::might_be_null>(), "reason_for_set", reason_for_set())
+ .member(SerialiserFlags<>(), "set_name", stringify(set_name()))
+ ;
+}
+
+const std::tr1::shared_ptr<Reason>
+Reason::deserialise(Deserialisation & d)
+{
+ if (d.class_name() == "TargetReason")
+ {
+ Deserialisator v(d, "TargetReason");
+ return make_shared_ptr(new TargetReason);
+ }
+ else if (d.class_name() == "PresetReason")
+ {
+ Deserialisator v(d, "PresetReason");
+ return make_shared_ptr(new PresetReason);
+ }
+ else if (d.class_name() == "SetReason")
+ {
+ Deserialisator v(d, "SetReason");
+ return make_shared_ptr(new SetReason(
+ SetName(v.member<std::string>("set_name")),
+ v.member<std::tr1::shared_ptr<Reason> >("reason_for_set")
+ ));
+ }
+ else if (d.class_name() == "DependencyReason")
+ {
+ Deserialisator v(d, "DependencyReason");
+ const std::tr1::shared_ptr<const PackageID> from_id(v.member<std::tr1::shared_ptr<const PackageID> >("from_id"));
+ return make_shared_ptr(new DependencyReason(
+ from_id,
+ SanitisedDependency::deserialise(*v.find_remove_member("sanitised_dependency"), from_id))
+ );
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
+}
+
template class PrivateImplementationPattern<DependencyReason>;
template class PrivateImplementationPattern<SetReason>;
diff --git a/paludis/resolver/reason.hh b/paludis/resolver/reason.hh
index d6cb177..3b0b2ee 100644
--- a/paludis/resolver/reason.hh
+++ b/paludis/resolver/reason.hh
@@ -23,6 +23,7 @@
#include <paludis/resolver/reason-fwd.hh>
#include <paludis/resolver/qpn_s-fwd.hh>
#include <paludis/resolver/sanitised_dependencies-fwd.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/simple_visitor.hh>
#include <paludis/util/type_list.hh>
@@ -41,6 +42,11 @@ namespace paludis
public:
virtual ~Reason() = 0;
virtual std::string as_string() const = 0;
+
+ virtual void serialise(Serialiser &) const = 0;
+
+ static const std::tr1::shared_ptr<Reason> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
class TargetReason :
@@ -49,6 +55,8 @@ namespace paludis
{
public:
virtual std::string as_string() const;
+
+ virtual void serialise(Serialiser &) const;
};
class DependencyReason :
@@ -67,6 +75,8 @@ namespace paludis
const SanitisedDependency & sanitised_dependency() const;
virtual std::string as_string() const;
+
+ virtual void serialise(Serialiser &) const;
};
class PresetReason :
@@ -75,6 +85,8 @@ namespace paludis
{
public:
virtual std::string as_string() const;
+
+ virtual void serialise(Serialiser &) const;
};
class SetReason :
@@ -90,6 +102,8 @@ namespace paludis
const std::tr1::shared_ptr<const Reason> reason_for_set() const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::string as_string() const;
+
+ virtual void serialise(Serialiser &) const;
};
}
diff --git a/paludis/resolver/resolution-fwd.hh b/paludis/resolver/resolution-fwd.hh
index 0345a2a..2167158 100644
--- a/paludis/resolver/resolution-fwd.hh
+++ b/paludis/resolver/resolution-fwd.hh
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTION_FWD_HH 1
#include <paludis/util/attributes.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <iosfwd>
namespace paludis
diff --git a/paludis/resolver/resolution.cc b/paludis/resolver/resolution.cc
index ef389cd..3e70938 100644
--- a/paludis/resolver/resolution.cc
+++ b/paludis/resolver/resolution.cc
@@ -21,10 +21,14 @@
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/arrow.hh>
#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/serialise-impl.hh>
+#include <paludis/resolver/destinations.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/join.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <sstream>
using namespace paludis;
@@ -45,3 +49,35 @@ paludis::resolver::operator<< (std::ostream & s, const Resolution & r)
return s;
}
+void
+Resolution::serialise(Serialiser & s) const
+{
+ s.object("Resolution")
+ .member(SerialiserFlags<>(), "already_ordered", already_ordered())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "arrows", arrows())
+ .member(SerialiserFlags<>(), "constraints", *constraints())
+ .member(SerialiserFlags<serialise::might_be_null>(), "decision", decision())
+ .member(SerialiserFlags<serialise::might_be_null>(), "destinations", destinations())
+ ;
+}
+
+const std::tr1::shared_ptr<Resolution>
+Resolution::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Resolution");
+
+ std::tr1::shared_ptr<ArrowSequence> arrows(new ArrowSequence);
+ Deserialisator vv(*v.find_remove_member("arrows"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ arrows->push_back(vv.member<std::tr1::shared_ptr<Arrow> >(stringify(n)));
+
+ return make_shared_ptr(new Resolution(make_named_values<Resolution>(
+ value_for<n::already_ordered>(v.member<bool>("already_ordered")),
+ value_for<n::arrows>(arrows),
+ value_for<n::constraints>(v.member<std::tr1::shared_ptr<Constraints> >("constraints")),
+ value_for<n::decision>(v.member<std::tr1::shared_ptr<Decision> >("decision")),
+ value_for<n::destinations>(v.member<std::tr1::shared_ptr<Destinations> >("destinations")),
+ value_for<n::sanitised_dependencies>(make_null_shared_ptr())
+ )));
+}
+
diff --git a/paludis/resolver/resolution.hh b/paludis/resolver/resolution.hh
index b89304a..d7d9307 100644
--- a/paludis/resolver/resolution.hh
+++ b/paludis/resolver/resolution.hh
@@ -51,6 +51,11 @@ namespace paludis
NamedValue<n::decision, std::tr1::shared_ptr<Decision> > decision;
NamedValue<n::destinations, std::tr1::shared_ptr<Destinations> > destinations;
NamedValue<n::sanitised_dependencies, std::tr1::shared_ptr<SanitisedDependencies> > sanitised_dependencies;
+
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Resolution> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/resolutions-fwd.hh b/paludis/resolver/resolutions-fwd.hh
index 4ecdefd..4fb6dfe 100644
--- a/paludis/resolver/resolutions-fwd.hh
+++ b/paludis/resolver/resolutions-fwd.hh
@@ -20,6 +20,9 @@
#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_FWD_HH
#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_FWD_HH 1
+#include <paludis/util/attributes.hh>
+#include <paludis/resolver/serialise-fwd.hh>
+
namespace paludis
{
namespace resolver
diff --git a/paludis/resolver/resolutions.cc b/paludis/resolver/resolutions.cc
index 37dcca4..afb7f69 100644
--- a/paludis/resolver/resolutions.cc
+++ b/paludis/resolver/resolutions.cc
@@ -18,9 +18,12 @@
*/
#include <paludis/resolver/resolutions.hh>
+#include <paludis/resolver/resolution.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <list>
+#include <paludis/util/sequence-impl.hh>
+#include <paludis/util/stringify.hh>
using namespace paludis;
using namespace paludis::resolver;
@@ -30,7 +33,7 @@ namespace paludis
template <>
struct Implementation<Resolutions>
{
- std::list<std::tr1::shared_ptr<const Resolution> > resolutions;
+ Sequence<std::tr1::shared_ptr<const Resolution> > resolutions;
};
}
@@ -61,6 +64,25 @@ Resolutions::end() const
return ConstIterator(_imp->resolutions.end());
}
+void
+Resolutions::serialise(Serialiser & s) const
+{
+ s.object("Resolutions")
+ .member(SerialiserFlags<serialise::container>(), "items", _imp->resolutions)
+ ;
+}
+
+const std::tr1::shared_ptr<Resolutions>
+Resolutions::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Resolutions");
+ Deserialisator vv(*v.find_remove_member("items"), "c");
+ std::tr1::shared_ptr<Resolutions> result(new Resolutions);
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->append(vv.member<std::tr1::shared_ptr<Resolution> >(stringify(n)));
+ return result;
+}
+
template class PrivateImplementationPattern<Resolutions>;
template class WrappedForwardIterator<Resolutions::ConstIteratorTag, const std::tr1::shared_ptr<const Resolution> >;
diff --git a/paludis/resolver/resolutions.hh b/paludis/resolver/resolutions.hh
index a2af9f4..1b246f4 100644
--- a/paludis/resolver/resolutions.hh
+++ b/paludis/resolver/resolutions.hh
@@ -46,6 +46,10 @@ namespace paludis
ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<Resolutions> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/resolver/sanitised_dependencies.cc b/paludis/resolver/sanitised_dependencies.cc
index 0ccad88..ac4bb48 100644
--- a/paludis/resolver/sanitised_dependencies.cc
+++ b/paludis/resolver/sanitised_dependencies.cc
@@ -20,6 +20,7 @@
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/resolver.hh>
#include <paludis/resolver/qpn_s.hh>
+#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/save.hh>
#include <paludis/util/stringify.hh>
@@ -30,6 +31,7 @@
#include <paludis/slot_requirement.hh>
#include <paludis/metadata_key.hh>
#include <paludis/package_id.hh>
+#include <paludis/user_dep_spec.hh>
#include <set>
#include <list>
@@ -417,5 +419,53 @@ PackageOrBlockDepSpec::PackageOrBlockDepSpec(const PackageDepSpec & s) :
{
}
+void
+PackageOrBlockDepSpec::serialise(Serialiser & s) const
+{
+ s.object("PackageOrBlockDepSpec")
+ .member(SerialiserFlags<>(), "if_block", if_block() ? stringify(*if_block()) : "null")
+ .member(SerialiserFlags<>(), "if_package", if_package() ? stringify(*if_package()) : "null")
+ ;
+}
+
+PackageOrBlockDepSpec
+PackageOrBlockDepSpec::deserialise(Deserialisation & d, const std::tr1::shared_ptr<const PackageID> & for_id)
+{
+ Deserialisator v(d, "PackageOrBlockDepSpec");
+
+ std::string if_block(v.member<std::string>("if_block"));
+ std::string if_package(v.member<std::string>("if_package"));
+
+ if (if_block == "null")
+ return PackageOrBlockDepSpec(parse_user_package_dep_spec(if_package,
+ d.deserialiser().environment(), UserPackageDepSpecOptions() + updso_serialised,
+ filter::All(), for_id));
+ else
+ return PackageOrBlockDepSpec(BlockDepSpec(make_shared_ptr(new PackageDepSpec(
+ parse_user_package_dep_spec(if_block.substr(if_block.find_first_not_of("!")),
+ d.deserialiser().environment(), UserPackageDepSpecOptions() + updso_serialised,
+ filter::All(), for_id))), if_block));
+}
+
+void
+SanitisedDependency::serialise(Serialiser & s) const
+{
+ s.object("SanitisedDependency")
+ .member(SerialiserFlags<>(), "spec", spec())
+ ;
+}
+
+SanitisedDependency
+SanitisedDependency::deserialise(Deserialisation & d, const std::tr1::shared_ptr<const PackageID> & from_id)
+{
+ Deserialisator v(d, "SanitisedDependency");
+
+ return make_named_values<SanitisedDependency>(
+ value_for<n::active_dependency_labels>(make_null_shared_ptr()),
+ value_for<n::spec>(PackageOrBlockDepSpec::deserialise(*v.find_remove_member("spec"),
+ from_id))
+ );
+}
+
template class WrappedForwardIterator<SanitisedDependencies::ConstIteratorTag, const SanitisedDependency>;
diff --git a/paludis/resolver/sanitised_dependencies.hh b/paludis/resolver/sanitised_dependencies.hh
index b2881cd..4678c14 100644
--- a/paludis/resolver/sanitised_dependencies.hh
+++ b/paludis/resolver/sanitised_dependencies.hh
@@ -22,6 +22,7 @@
#include <paludis/resolver/sanitised_dependencies-fwd.hh>
#include <paludis/resolver/resolver-fwd.hh>
+#include <paludis/resolver/serialise-fwd.hh>
#include <paludis/util/named_value.hh>
#include <paludis/dep_label-fwd.hh>
#include <paludis/dep_spec.hh>
@@ -47,12 +48,24 @@ namespace paludis
PackageOrBlockDepSpec(const BlockDepSpec &);
PackageOrBlockDepSpec(const PackageDepSpec &);
+
+ void serialise(Serialiser &) const;
+
+ static PackageOrBlockDepSpec deserialise(
+ Deserialisation & d,
+ const std::tr1::shared_ptr<const PackageID> & for_id) PALUDIS_ATTRIBUTE((warn_unused_result));
};
struct SanitisedDependency
{
NamedValue<n::active_dependency_labels, std::tr1::shared_ptr<const ActiveDependencyLabels> > active_dependency_labels;
NamedValue<n::spec, PackageOrBlockDepSpec> spec;
+
+ void serialise(Serialiser &) const;
+
+ static SanitisedDependency deserialise(
+ Deserialisation & d,
+ const std::tr1::shared_ptr<const PackageID> & for_id) PALUDIS_ATTRIBUTE((warn_unused_result));
};
class SanitisedDependencies :
diff --git a/paludis/resolver/serialise-fwd.hh b/paludis/resolver/serialise-fwd.hh
new file mode 100644
index 0000000..c84d4ae
--- /dev/null
+++ b/paludis/resolver/serialise-fwd.hh
@@ -0,0 +1,34 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_SERIALISE_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_SERIALISE_FWD_HH 1
+
+namespace paludis
+{
+ namespace resolver
+ {
+ struct Serialiser;
+
+ struct Deserialiser;
+ struct Deserialisation;
+ }
+}
+
+#endif
diff --git a/paludis/resolver/serialise-impl.hh b/paludis/resolver/serialise-impl.hh
new file mode 100644
index 0000000..19d7aea
--- /dev/null
+++ b/paludis/resolver/serialise-impl.hh
@@ -0,0 +1,229 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_SERIALISE_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_SERIALISE_IMPL_HH 1
+
+#include <paludis/resolver/serialise.hh>
+#include <paludis/util/remove_shared_ptr.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/package_id-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
+#include <tr1/type_traits>
+#include <ostream>
+#include <istream>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ template <
+ typename Flags_,
+ typename Flag_>
+ struct SerialiserFlagsInclude
+ {
+ static const bool value =
+ std::tr1::is_same<typename Flags_::Flag1, Flag_>::value ||
+ std::tr1::is_same<typename Flags_::Flag2, Flag_>::value ||
+ std::tr1::is_same<typename Flags_::Flag3, Flag_>::value;
+ };
+
+ template <
+ bool is_container_,
+ bool might_be_null_,
+ typename T_>
+ struct SerialiserObjectWriterHandler;
+
+ template <>
+ struct SerialiserObjectWriterHandler<false, false, bool>
+ {
+ static void write(Serialiser & s, const bool t);
+ };
+
+ template <>
+ struct SerialiserObjectWriterHandler<false, false, int>
+ {
+ static void write(Serialiser & s, const int t);
+ };
+
+ template <>
+ struct SerialiserObjectWriterHandler<false, false, std::string>
+ {
+ static void write(Serialiser & s, const std::string & t);
+ };
+
+ template <>
+ struct SerialiserObjectWriterHandler<false, false, const PackageID>
+ {
+ static void write(Serialiser & s, const PackageID & t);
+ };
+
+ template <
+ typename T_>
+ struct SerialiserObjectWriterHandler<false, false, T_>
+ {
+ static void write(Serialiser & s, const T_ & t)
+ {
+ t.serialise(s);
+ }
+ };
+
+ template <
+ bool is_container_,
+ typename T_>
+ struct SerialiserObjectWriterHandler<is_container_, true, T_>
+ {
+ static void write(Serialiser & s, const T_ & t)
+ {
+ if (t)
+ SerialiserObjectWriterHandler<is_container_, false, typename RemoveSharedPtr<T_>::Type>::write(
+ s, *t);
+ else
+ s.raw_stream() << "null;";
+ }
+ };
+
+ template <
+ typename T_>
+ struct SerialiserObjectWriterHandler<true, false, T_>
+ {
+ static void write(Serialiser & s, const T_ & t)
+ {
+ s.raw_stream() << "c(";
+ unsigned n(0);
+ for (typename T_::ConstIterator i(t.begin()), i_end(t.end()) ;
+ i != i_end ; ++i)
+ {
+ typedef typename std::iterator_traits<typename T_::ConstIterator>::value_type ItemValueType;
+ typedef typename std::tr1::remove_reference<ItemValueType>::type ItemType;
+
+ s.raw_stream() << ++n << "=";
+ SerialiserObjectWriterHandler<
+ false,
+ ! std::tr1::is_same<ItemType, typename RemoveSharedPtr<ItemType>::Type>::value,
+ ItemType
+ >::write(s, *i);
+ }
+
+ s.raw_stream() << "count=";
+ SerialiserObjectWriterHandler<false, false, int>::write(s, n);
+
+ s.raw_stream() << ");";
+ }
+ };
+
+ template <
+ typename Flags_,
+ typename T_>
+ SerialiserObjectWriter &
+ SerialiserObjectWriter::member(
+ const Flags_ &,
+ const std::string & item_name,
+ const T_ & t)
+ {
+ _serialiser.raw_stream() << item_name << "=";
+
+ SerialiserObjectWriterHandler<
+ SerialiserFlagsInclude<Flags_, serialise::container>::value,
+ SerialiserFlagsInclude<Flags_, serialise::might_be_null>::value,
+ T_
+ >::write(_serialiser, t);
+
+ return *this;
+ }
+
+ template <typename T_>
+ struct DeserialisatorHandler;
+
+ template <>
+ struct DeserialisatorHandler<bool>
+ {
+ static bool handle(Deserialisation & v)
+ {
+ return destringify<bool>(v.string_value());
+ }
+ };
+
+ template <>
+ struct DeserialisatorHandler<int>
+ {
+ static int handle(Deserialisation & v)
+ {
+ return destringify<int>(v.string_value());
+ }
+ };
+
+ template <>
+ struct DeserialisatorHandler<std::string>
+ {
+ static std::string handle(Deserialisation & v)
+ {
+ return v.string_value();
+ }
+ };
+
+ template <>
+ struct DeserialisatorHandler<std::tr1::shared_ptr<const PackageID> >
+ {
+ static std::tr1::shared_ptr<const PackageID> handle(Deserialisation & v);
+ };
+
+ template <typename T_>
+ struct DeserialisatorHandler<std::tr1::shared_ptr<T_> >
+ {
+ static std::tr1::shared_ptr<T_> handle(Deserialisation & v)
+ {
+ if (v.null())
+ return make_null_shared_ptr();
+ else
+ return T_::deserialise(v);
+ }
+ };
+
+ template <typename T_>
+ struct DeserialisatorHandler
+ {
+ static T_ handle(Deserialisation & v)
+ {
+ return T_::deserialise(v);
+ }
+ };
+
+ template <typename T_>
+ T_
+ Deserialisator::member(const std::string & key_name)
+ {
+ return DeserialisatorHandler<T_>::handle(*find_remove_member(key_name));
+ }
+
+ template <typename T_>
+ std::tr1::shared_ptr<T_> deserialise(
+ const Environment * const env,
+ const std::string & str,
+ const std::string & class_name)
+ {
+ Deserialiser d(env, str);
+ Deserialisation dd(class_name, d);
+ return T_::deserialise(dd);
+ }
+ }
+}
+
+#endif
diff --git a/paludis/resolver/serialise.cc b/paludis/resolver/serialise.cc
new file mode 100644
index 0000000..3a90b96
--- /dev/null
+++ b/paludis/resolver/serialise.cc
@@ -0,0 +1,340 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/resolver/serialise-impl.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/simple_parser.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/member_iterator-impl.hh>
+#include <paludis/package_id.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/selection.hh>
+#include <paludis/filter.hh>
+#include <paludis/generator.hh>
+#include <paludis/filtered_generator.hh>
+#include <list>
+#include <map>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+SerialiserObjectWriter::SerialiserObjectWriter(Serialiser & s) :
+ _serialiser(s)
+{
+}
+
+SerialiserObjectWriter::~SerialiserObjectWriter()
+{
+ _serialiser.raw_stream() << ");";
+}
+
+Serialiser::Serialiser(std::ostream & s) :
+ _stream(s)
+{
+}
+
+Serialiser::~Serialiser()
+{
+}
+
+std::ostream &
+Serialiser::raw_stream()
+{
+ return _stream;
+}
+
+SerialiserObjectWriter
+Serialiser::object(const std::string & c)
+{
+ raw_stream() << c << "(";
+ return SerialiserObjectWriter(*this);
+}
+
+void
+SerialiserObjectWriterHandler<false, false, bool>::write(Serialiser & s, const bool t)
+{
+ if (t)
+ s.raw_stream() << "\"true\";";
+ else
+ s.raw_stream() << "\"false\";";
+}
+
+void
+SerialiserObjectWriterHandler<false, false, int>::write(Serialiser & s, const int i)
+{
+ s.raw_stream() << "\"" << i << "\";";
+}
+
+void
+SerialiserObjectWriterHandler<false, false, std::string>::write(Serialiser & s, const std::string & t)
+{
+ s.raw_stream() << "\"";
+ s.escape_write(t);
+ s.raw_stream() << "\";";
+}
+
+void
+SerialiserObjectWriterHandler<false, false, const PackageID>::write(Serialiser & s, const PackageID & t)
+{
+ s.raw_stream() << "\"";
+ s.escape_write(stringify(t.uniquely_identifying_spec()));
+ s.raw_stream() << "\";";
+}
+
+void
+Serialiser::escape_write(const std::string & t)
+{
+ for (std::string::const_iterator c(t.begin()), c_end(t.end()) ;
+ c != c_end ; ++c)
+ switch (*c)
+ {
+ case '\\':
+ case '"':
+ case ';':
+ case '(':
+ case ')':
+ raw_stream() << '\\';
+ /* fall through */
+ default:
+ raw_stream() << *c;
+ }
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<Deserialiser>
+ {
+ const Environment * const env;
+ SimpleParser parser;
+
+ Implementation(const Environment * const e, const std::string & s) :
+ env(e),
+ parser(s)
+ {
+ }
+ };
+
+ template <>
+ struct Implementation<Deserialisation>
+ {
+ Deserialiser & deserialiser;
+ const std::string item_name;
+
+ std::string class_name;
+ std::string string_value;
+ bool null;
+ std::list<std::tr1::shared_ptr<Deserialisation> > children;
+
+ Implementation(Deserialiser & d, const std::string & i) :
+ deserialiser(d),
+ item_name(i),
+ null(false)
+ {
+ }
+ };
+
+ template <>
+ struct Implementation<Deserialisator>
+ {
+ const std::string class_name;
+ std::map<std::string, std::tr1::shared_ptr<Deserialisation> > keys;
+
+ Implementation(const std::string & c) :
+ class_name(c)
+ {
+ }
+ };
+}
+
+Deserialiser::Deserialiser(const Environment * const e, const std::string & s) :
+ PrivateImplementationPattern<Deserialiser>(new Implementation<Deserialiser>(e, s))
+{
+}
+
+Deserialiser::~Deserialiser()
+{
+}
+
+SimpleParser &
+Deserialiser::parser()
+{
+ return _imp->parser;
+}
+
+const Environment *
+Deserialiser::environment() const
+{
+ return _imp->env;
+}
+
+Deserialisation::Deserialisation(const std::string & i, Deserialiser & d) :
+ PrivateImplementationPattern<Deserialisation>(new Implementation<Deserialisation>(d, i))
+{
+ if (d.parser().consume(simple_parser::exact("null;")))
+ _imp->null = true;
+ else if (d.parser().consume(simple_parser::exact("\"")))
+ {
+ while (true)
+ {
+ std::string v;
+ if (d.parser().consume(simple_parser::exact("\\")))
+ {
+ if (! d.parser().consume(simple_parser::any_except("") >> v))
+ throw InternalError(PALUDIS_HERE, "can't parse string escape");
+ _imp->string_value.append(v);
+ }
+ else if (d.parser().consume(simple_parser::exact("\";")))
+ break;
+ else if (d.parser().consume((+simple_parser::any_except("\\\"")) >> v))
+ _imp->string_value.append(v);
+ else
+ throw InternalError(PALUDIS_HERE, "can't parse string");
+ }
+ }
+ else if (d.parser().consume(((+simple_parser::any_of(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_"
+ )) >> _imp->class_name)
+ & simple_parser::exact("(")))
+ {
+ while (true)
+ {
+ std::string k;
+ if (d.parser().consume(simple_parser::exact(");")))
+ break;
+ else if (d.parser().consume(((+simple_parser::any_of(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "-_"
+ )) >> k)
+ & simple_parser::exact("=")))
+ {
+ std::tr1::shared_ptr<Deserialisation> c(new Deserialisation(k, d));
+ _imp->children.push_back(c);
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "can't parse keys, remaining text is '"
+ + d.parser().text().substr(d.parser().offset()));
+ }
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "can't parse keys, remaining text is '"
+ + d.parser().text().substr(d.parser().offset()));
+}
+
+Deserialisation::~Deserialisation()
+{
+}
+
+const std::string
+Deserialisation::item_name() const
+{
+ return _imp->item_name;
+}
+
+const std::string
+Deserialisation::class_name() const
+{
+ return _imp->class_name;
+}
+
+bool
+Deserialisation::null() const
+{
+ return _imp->null;
+}
+
+const std::string
+Deserialisation::string_value() const
+{
+ return _imp->string_value;
+}
+
+Deserialisation::ConstIterator
+Deserialisation::begin_children() const
+{
+ return ConstIterator(_imp->children.begin());
+}
+
+Deserialisation::ConstIterator
+Deserialisation::end_children() const
+{
+ return ConstIterator(_imp->children.end());
+}
+
+const Deserialiser &
+Deserialisation::deserialiser() const
+{
+ return _imp->deserialiser;
+}
+
+Deserialisator::Deserialisator(Deserialisation & d, const std::string & c) :
+ PrivateImplementationPattern<Deserialisator>(new Implementation<Deserialisator>(c))
+{
+ if (c != d.class_name())
+ throw InternalError(PALUDIS_HERE, "expected class name '" + stringify(c) + "' but got '"
+ + d.class_name() + "'");
+
+ for (Deserialisation::ConstIterator i(d.begin_children()), i_end(d.end_children()) ;
+ i != i_end ; ++i)
+ _imp->keys.insert(std::make_pair((*i)->item_name(), *i));
+}
+
+Deserialisator::~Deserialisator()
+{
+ if (! std::uncaught_exception())
+ {
+ if (! _imp->keys.empty())
+ throw InternalError(PALUDIS_HERE, "keys not empty when deserialising '" + _imp->class_name + "', keys remaining are { "
+ + join(first_iterator(_imp->keys.begin()), first_iterator(_imp->keys.end()), ", ") + " }");
+ }
+}
+
+const std::tr1::shared_ptr<Deserialisation>
+Deserialisator::find_remove_member(const std::string & s)
+{
+ std::map<std::string, std::tr1::shared_ptr<Deserialisation> >::iterator i(_imp->keys.find(s));
+ if (i == _imp->keys.end())
+ throw InternalError(PALUDIS_HERE, "no key '" + s + "'");
+ std::tr1::shared_ptr<Deserialisation> result(i->second);
+ _imp->keys.erase(i);
+ return result;
+}
+
+std::tr1::shared_ptr<const PackageID>
+DeserialisatorHandler<std::tr1::shared_ptr<const PackageID> >::handle(Deserialisation & v)
+{
+ return *(*v.deserialiser().environment())[
+ selection::RequireExactlyOne(generator::Matches(
+ parse_user_package_dep_spec(v.string_value(), v.deserialiser().environment(),
+ UserPackageDepSpecOptions() + updso_serialised), MatchPackageOptions()))]->begin();
+}
+
+template class PrivateImplementationPattern<Deserialiser>;
+template class PrivateImplementationPattern<Deserialisation>;
+template class PrivateImplementationPattern<Deserialisator>;
+
diff --git a/paludis/resolver/serialise.hh b/paludis/resolver/serialise.hh
new file mode 100644
index 0000000..6262e1b
--- /dev/null
+++ b/paludis/resolver/serialise.hh
@@ -0,0 +1,158 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_SERIALISE_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_SERIALISE_HH 1
+
+#include <paludis/resolver/serialise-fwd.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/simple_parser-fwd.hh>
+#include <paludis/util/wrapped_forward_iterator-fwd.hh>
+#include <paludis/environment-fwd.hh>
+#include <tr1/memory>
+#include <string>
+#include <ostream>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ namespace serialise
+ {
+ struct container;
+ struct might_be_null;
+ }
+
+ template <
+ typename Flag1_ = void,
+ typename Flag2_ = void,
+ typename Flag3_ = void
+ >
+ struct SerialiserFlags
+ {
+ typedef Flag1_ Flag1;
+ typedef Flag2_ Flag2;
+ typedef Flag3_ Flag3;
+ };
+
+ class PALUDIS_VISIBLE SerialiserObjectWriter
+ {
+ private:
+ Serialiser & _serialiser;
+
+ public:
+ SerialiserObjectWriter(Serialiser &);
+ ~SerialiserObjectWriter();
+
+ template <
+ typename Flags_,
+ typename T_>
+ SerialiserObjectWriter & member(
+ const Flags_ &,
+ const std::string & item_name,
+ const T_ &);
+ };
+
+ class PALUDIS_VISIBLE Serialiser
+ {
+ private:
+ std::ostream & _stream;
+
+ public:
+ Serialiser(std::ostream &);
+ ~Serialiser();
+
+ SerialiserObjectWriter object(const std::string & class_name)
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::ostream & raw_stream() PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ void escape_write(const std::string &);
+ };
+
+ class PALUDIS_VISIBLE Deserialiser :
+ private PrivateImplementationPattern<Deserialiser>
+ {
+ public:
+ Deserialiser(const Environment * const, const std::string &);
+ ~Deserialiser();
+
+ const Environment * environment() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ SimpleParser & parser() PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE Deserialisation :
+ private PrivateImplementationPattern<Deserialisation>
+ {
+ public:
+ Deserialisation(const std::string &, Deserialiser &);
+ ~Deserialisation();
+
+ const Deserialiser & deserialiser() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ const std::string item_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ const std::string class_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ const std::string string_value() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ bool null() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ struct ConstIteratorTag;
+ typedef WrappedForwardIterator<ConstIteratorTag,
+ const std::tr1::shared_ptr<Deserialisation> > ConstIterator;
+ ConstIterator begin_children() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator end_children() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE Deserialisator :
+ private PrivateImplementationPattern<Deserialisator>
+ {
+ public:
+ Deserialisator(
+ Deserialisation &,
+ const std::string & class_name);
+
+ ~Deserialisator();
+
+ const Deserialisation & deserialisation() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ template <typename T_> T_ member(const std::string & key_name);
+
+ const std::tr1::shared_ptr<Deserialisation> find_remove_member(
+ const std::string &) PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ };
+
+ template <typename T_>
+ std::tr1::shared_ptr<T_> deserialise(
+ const Environment * const,
+ const std::string &,
+ const std::string &) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<resolver::Deserialiser>;
+ extern template class PrivateImplementationPattern<resolver::Deserialisation>;
+ extern template class PrivateImplementationPattern<resolver::Deserialisator>;
+#endif
+}
+
+#endif
diff --git a/paludis/resolver/use_installed.se b/paludis/resolver/use_installed.se
index ec6e438..1ff9b09 100644
--- a/paludis/resolver/use_installed.se
+++ b/paludis/resolver/use_installed.se
@@ -12,5 +12,7 @@ make_enum_UseInstalled()
key ui_if_same "If it is the same"
key ui_if_same_version "If it is the same version"
key ui_if_possible "If possible"
+
+ want_destringify
}
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index 6ac09b0..c9c6fa2 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -41,6 +41,8 @@
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/destinations.hh>
+#include <paludis/resolver/serialise-impl.hh>
+#include <paludis/resolver/resolutions.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/generator.hh>
@@ -616,7 +618,14 @@ ResolveCommand::run(
}
}
- display_resolution(env, resolver, cmdline);
+ std::stringstream ser;
+ Serialiser s(ser);
+ resolver->resolutions()->serialise(s);
+
+ std::tr1::shared_ptr<Resolutions> copied_resolutions(deserialise<Resolutions>(
+ env.get(), ser.str(), "Resolutions"));
+
+ display_resolution(env, copied_resolutions, cmdline);
display_explanations(env, resolver, cmdline);
}
catch (...)
diff --git a/src/clients/cave/cmd_resolve_display_resolution.cc b/src/clients/cave/cmd_resolve_display_resolution.cc
index f5ea9a6..6a6e95b 100644
--- a/src/clients/cave/cmd_resolve_display_resolution.cc
+++ b/src/clients/cave/cmd_resolve_display_resolution.cc
@@ -76,14 +76,14 @@ namespace
void
paludis::cave::display_resolution(
const std::tr1::shared_ptr<Environment> &,
- const std::tr1::shared_ptr<Resolver> & resolver,
+ const std::tr1::shared_ptr<Resolutions> & resolutions,
const ResolveCommandLine &)
{
Context context("When displaying chosen resolution:");
std::cout << "These are the actions I will take, in order:" << std::endl << std::endl;
- for (Resolutions::ConstIterator c(resolver->resolutions()->begin()), c_end(resolver->resolutions()->end()) ;
+ for (Resolutions::ConstIterator c(resolutions->begin()), c_end(resolutions->end()) ;
c != c_end ; ++c)
{
const std::tr1::shared_ptr<const PackageID> id((*c)->decision()->if_package_id());
diff --git a/src/clients/cave/cmd_resolve_display_resolution.hh b/src/clients/cave/cmd_resolve_display_resolution.hh
index ded734e..472d7a0 100644
--- a/src/clients/cave/cmd_resolve_display_resolution.hh
+++ b/src/clients/cave/cmd_resolve_display_resolution.hh
@@ -21,7 +21,7 @@
#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_RESOLVE_DISPLAY_RESOLUTION_HH 1
#include <paludis/environment-fwd.hh>
-#include <paludis/resolver/resolver-fwd.hh>
+#include <paludis/resolver/resolutions-fwd.hh>
#include "cmd_resolve_cmdline.hh"
namespace paludis
@@ -30,7 +30,7 @@ namespace paludis
{
void display_resolution(
const std::tr1::shared_ptr<Environment> &,
- const std::tr1::shared_ptr<resolver::Resolver> & resolver,
+ const std::tr1::shared_ptr<resolver::Resolutions> &,
const ResolveCommandLine &);
}
}