00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef MORE_NET_DIRECTORY_H
00030 #define MORE_NET_DIRECTORY_H
00031
00032 #include <more/bits/experimental.h>
00033
00034 namespace more {
00035 namespace net {
00036
00037 template<typename Object>
00038 struct dynamic_object
00039 {
00040 operator=(Object const& o) const;
00041 };
00042
00043
00044 struct directory
00045 {
00046 enum state_type
00047 {
00048 state_incomplete,
00049 state_unchanged,
00050 state_added,
00051 state_replaced,
00052 state_deleted
00053 };
00054
00055 struct attribute
00056 {
00057 std::string const& key() const;
00058 std::string const& value() const;
00059 void set_value(std::string const&);
00060
00061
00062 private:
00063 state_type m_state;
00064 std::string m_key;
00065 std::string m_value;
00066 };
00067
00068 typedef std::multimap<std::string, attr_value> attr_map;
00069
00070 struct entry
00071 {
00072 explicit entry(std::string const& rdn)
00073 : m_state(state_incomplete), m_rdn(rdn) {}
00074
00075 std::string const& rdn();
00076 void insert(std::pair<std::string, std::string> const& attr);
00077 void commit();
00078
00079 std::string get(std::string const& tag);
00080 void put(std::string const& tag, std::string const& tag);
00081 io::gistream get_streamed(std::string const& tag);
00082 io::gostream insert_streamed(std::string const& tag);
00083
00084 bool operator<(entry const& rhs) const { return rdn() < rhs.rdn(); }
00085
00086 private:
00087 state_type m_state;
00088 std::string m_rdn;
00089 attr_map m_attrs;
00090 unsigned int m_name_ref_cnt;
00091 unsigned int m_full_ref_cnt;
00092 unsigned int m_unfold_cnt;
00093 };
00094
00095 private:
00096 typedef gen::ntree<entry, std::set> entry_tree;
00097 typedef entry_tree::iterator entry_iterator;
00098 typedef entry_tree::const_iterator entry_const_iterator;
00099
00100 public:
00101 struct full_one_range : gen::noncopyable
00102 {
00103 typedef entry_iterator iterator;
00104 typedef entry_const_iterator const_iterator;
00105
00106 full_one_range(directory& dir, iterator it_cxt)
00107 : m_dir(&dir),
00108 m_it_cxt(it_cxt)
00109 {
00110 m_dir->unfold(it_cxt);
00111 }
00112
00113 full_one_range(full_one_range const& rng)
00114 : m_dir(rng.dir),
00115 m_it_cxt(rng.m_it_cxt)
00116 {
00117 m_dir->unfold(m_it_cxt);
00118 }
00119
00120 full_one_range& operator=(full_one_range const& rng)
00121 {
00122 m_dir->fold(m_it_cxt);
00123 m_dir = rng.m_dir;
00124 m_it_cxt = rng.m_it_cxt;
00125 m_dir->unfold(m_it_cxt);
00126 }
00127
00128 ~full_one_range()
00129 {
00130 m_dir->fold(m_it_cxt);
00131 }
00132
00133 iterator begin() { return m_it_cxt->branches().begin(); }
00134 iterator end() { return m_it_cxt->branches().end(); }
00135
00136 private:
00137 directory* m_dir;
00138 iterator m_it_cxt;
00139 };
00140
00141 struct full_one_iterator
00142 : std::iterator<std::bidirectional_iterator_tag, entry>
00143 {
00144 full_one_iterator(directory* dir, entry_iterator const& subit)
00145 : m_dir(dir), m_subit(subit)
00146 {
00147 m_dir->unfold(subit);
00148 }
00149
00150 ~full_one_iterator()
00151 {
00152 m_dir->fold(m_subit);
00153 }
00154
00155 full_one_iterator(full_one_iterator const& it)
00156 : m_dir(it.m_dir),
00157 m_subit(it.m_subit)
00158 {
00159 ++m_subit->m_unfold_count;
00160 }
00161
00162 full_one_iterator& operator=(full_one_iterator const& rhs)
00163 {
00164 m_dir->fold(m_subit);
00165 m_dir = rhs.m_dir;
00166 m_subit = rhs.m_subit;
00167 ++m_subit->m_unfold_count;
00168 }
00169
00170 full_one_iterator& operator++() { ++m_subit; return *this; }
00171 full_one_iterator& operator--() { --m_subit; return *this; }
00172
00173 full_one_iterator operator++(int)
00174 {
00175 full_one_iterator tmp(*this);
00176 ++*this;
00177 return tmp;
00178 }
00179
00180 full_one_iterator operator--(int)
00181 {
00182 full_one_iterator tmp(*this);
00183 --*this;
00184 return tmp;
00185 }
00186
00187 entry& operator*() { return *m_subit; }
00188 entry* operator->() { return m_subit->operator->(); }
00189
00190 private:
00191 directory* m_dir;
00192 entry_iterator m_subit;
00193 };
00194
00195 explicit directory(std::string server);
00196
00197 iterator root() { return m_tree.root(); }
00198 const_iterator root() const { return m_tree.root(); }
00199
00200 private:
00201 void unfold(iterator it);
00202 void fold(iterator it);
00203
00204 entry_tree m_tree;
00205 };
00206
00207 }}
00208 #endif