--- /dev/null
+#include "annotations.hpp"
+
+const std::string Annotations::name_str("name");
+
+Annotations::Annotations()
+{
+ metadata[name_str] = "";
+}
+
+Annotations::Annotations(const std::string &n)
+{
+ metadata[name_str] = n;
+}
+
+Annotations::Annotations(const Annotations& a) :
+ metadata(a.metadata)
+{
+}
+
+Annotations::Annotations(const AnnotationsRef a) :
+ metadata(a->metadata)
+{
+}
+
+AnnotationsRef Annotations::copy() const
+{
+ AnnotationsRef a(new Annotations(*this));
+ return a;
+}
+
+void Annotations::erase(const std::string& key)
+{
+ if (key == name_str) {
+ // we must always have a name
+ metadata[key] = "";
+ } else {
+ metadata.erase(key);
+ }
+}
+
+void Annotations::set(const std::string& key, const std::string &value )
+{
+ metadata[key] = value;
+}
+
+std::string Annotations::get(const std::string& key) const
+{
+ metadata_map::const_iterator map_i(metadata.find(key));
+ if (map_i == metadata.end()) {
+ throw annotations_key_error(key + " was not found");
+ } else {
+ return map_i->second;
+ }
+}
+
+bool Annotations::has_key(const std::string& key) const
+{
+ metadata_map::const_iterator map_i(metadata.find(key));
+ return map_i != metadata.end();
+}
\ No newline at end of file
--- /dev/null
+#ifndef ANNOTATIONS_HPP_
+#define ANNOTATIONS_HPP_
+
+#include <string>
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+
+#include "mussa_exceptions.hpp"
+
+class Annotations;
+typedef boost::shared_ptr<Annotations> AnnotationsRef;
+
+/**
+ * \brief Annotations provides a simple "dictionary" of name value pairs
+ *
+ * The intent is that this is to be used as a mix-in class to add
+ * a uniform way of storing annotation metadata.
+ */
+class Annotations {
+protected:
+ static const std::string name_str;
+
+public:
+ typedef std::map<std::string, std::string> metadata_map;
+ typedef metadata_map::size_type size_type;
+
+ Annotations();
+ Annotations(const std::string& n);
+ Annotations(const Annotations&);
+ Annotations(const AnnotationsRef);
+
+ //! make a shared pointer copy of our object
+ AnnotationsRef copy() const;
+
+ //! provide a special case for accessing a name
+ std::string name() const { return metadata.find(name_str)->second; }
+ //! special case for setting name
+ void setName(const std::string& n) { metadata[name_str] = n; }
+
+ //! Generic metadata handling
+ //@{
+ //! remove some key from our "dictionary"
+ void erase(const std::string& key);
+ //! set a metadata element
+ void set(const std::string& key, const std::string &value );
+ //! look for a key, \throws annotation_key_error if it doesn't find it
+ std::string get(const std::string& key) const;
+ //! check for a key
+ bool has_key(const std::string& key) const;
+ //! return all the keys of our metadata map
+ //std::list<std::string> keys() const;
+ size_type size() const { return metadata.size(); }
+ //@}
+protected:
+ metadata_map metadata;
+};
+#endif /*ANNOTATIONS_HPP_*/
#add all our main tests
MAKE_ALG_UNITTEST( test_alphabet )
+MAKE_ALG_UNITTEST( test_annotations )
MAKE_ALG_UNITTEST( test_annotation_color )
MAKE_ALG_UNITTEST( test_color )
MAKE_ALG_UNITTEST( test_conserved_path )
--- /dev/null
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+
+#include <boost/shared_ptr.hpp>
+#include "annotations.hpp"
+#include "mussa_exceptions.hpp"
+
+BOOST_AUTO_TEST_CASE( annotations_constructors )
+{
+ Annotations a;
+ BOOST_CHECK_EQUAL(a.name(), "");
+
+ Annotations b("bee");
+ BOOST_CHECK_EQUAL(b.name(), "bee");
+
+ boost::shared_ptr<Annotations> asp(new Annotations);
+ BOOST_CHECK_EQUAL(asp->name(), "");
+
+ boost::shared_ptr<Annotations> bsp(new Annotations("bee pointer"));
+ BOOST_CHECK_EQUAL(bsp->name(), "bee pointer");
+}
+
+BOOST_AUTO_TEST_CASE( annotations_copy_constructor )
+{
+ AnnotationsRef a(new Annotations("a"));
+ AnnotationsRef b(a);
+ AnnotationsRef c(new Annotations(a));
+
+ // b is a copy of a's pointer and thus changes
+ // to b update a
+ b->setName("bee");
+ BOOST_CHECK_EQUAL(a->name(), "bee");
+ BOOST_CHECK_EQUAL(b->name(), "bee");
+
+ // c is a copy of a, and not a pointer to a
+ // so updates of a, b wont affect c and vice versa
+ BOOST_CHECK_EQUAL(c->name(), "a");
+ c->setName("cee");
+ BOOST_CHECK_EQUAL(c->name(), "cee");
+
+ BOOST_CHECK_EQUAL(a->name(), "bee");
+ BOOST_CHECK_EQUAL(b->name(), "bee");
+
+}
+
+BOOST_AUTO_TEST_CASE( annotations_get_metadata )
+{
+ boost::shared_ptr<Annotations> asp(new Annotations("asp"));
+ asp->set("header", "> amsp");
+
+ BOOST_CHECK_EQUAL( asp->size(), 2 );
+ BOOST_CHECK_EQUAL( asp->get("header"), "> amsp" );
+ BOOST_CHECK_THROW( asp->get("not there"), annotations_key_error );
+}
+
+BOOST_AUTO_TEST_CASE( annotations_has_key )
+{
+ boost::shared_ptr<Annotations> asp(new Annotations("asp"));
+ asp->set("header", "> amsp");
+
+ BOOST_CHECK_EQUAL(asp->has_key("header"), true);
+ BOOST_CHECK_EQUAL(asp->has_key("name"), true);
+ BOOST_CHECK_EQUAL(asp->has_key("secret"), false);
+}
\ No newline at end of file