document_info.hpp

Go to the documentation of this file.
00001 /* libobby - Network text editing library
00002  * Copyright (C) 2005, 2006 0x539 dev group
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public
00015  * License along with this program; if not, write to the Free
00016  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 #ifndef _OBBY_DOCUMENT_INFO_HPP_
00020 #define _OBBY_DOCUMENT_INFO_HPP_
00021 
00022 #include <algorithm>
00023 #include <sigc++/signal.h>
00024 #include <net6/object.hpp>
00025 #include "position.hpp"
00026 #include "ptr_iterator.hpp"
00027 #include "format_string.hpp"
00028 #include "command.hpp"
00029 #include "user.hpp"
00030 #include "document_packet.hpp"
00031 #include "serialise/object.hpp"
00032 
00033 namespace obby
00034 {
00035 
00036 template<typename Document, typename Selector>
00037 class basic_buffer;
00038 
00042 template<typename Document, typename Selector>
00043 class basic_document_info: private net6::non_copyable, public sigc::trackable
00044 {
00045 public:
00046         class privileges
00047         {
00048         public:
00049                 static const privileges NONE;
00050                 static const privileges SUBSCRIBE;
00051                 static const privileges MODIFY;
00052                 static const privileges CLOSE;
00053                 static const privileges RENAME;
00054                 static const privileges ADMIN;
00055                 static const privileges ALL;
00056 
00057                 privileges operator|(privileges other) const
00058                 {
00059                         return privileges(m_value | other.m_value);
00060                 }
00061 
00062                 privileges operator&(privileges other) const
00063                 {
00064                         return privileges(m_value & other.m_value);
00065                 }
00066 
00067                 privileges operator^(privileges other) const
00068                 {
00069                         return privileges(m_value ^ other.m_value);
00070                 }
00071 
00072                 privileges& operator|=(privileges other)
00073                 {
00074                         m_value |= other.m_value; return *this;
00075                 }
00076 
00077                 privileges& operator&=(privileges other)
00078                 {
00079                         m_value &= other.m_value; return *this;
00080                 }
00081 
00082                 privileges& operator^=(privileges other)
00083                 {
00084                         m_value ^= other.m_value; return *this;
00085                 }
00086 
00087                 privileges operator~() const
00088                 {
00089                         return privileges(~m_value);
00090                 }
00091 
00092                 operator bool() const { return m_value != NONE.m_value; }
00093                 bool operator!() const { return m_value == NONE.m_value; }
00094 
00095                 bool operator==(privileges other) const
00096                 {
00097                         return m_value == other.m_value;
00098                 }
00099 
00100                 bool operator!=(privileges other) const
00101                 {
00102                         return m_value != other.m_value;
00103                 }
00104 
00105                 unsigned int get_value() const { return m_value; }
00106 
00107         protected:
00108                 explicit privileges(unsigned int value) : m_value(value) { }
00109 
00110                 unsigned int m_value;
00111         };
00112 
00113         typedef Document document_type;
00114         typedef Selector selector_type;
00115 
00116         class privileges_table;
00117 
00118         typedef sigc::signal<void, const std::string&> signal_rename_type;
00119         typedef sigc::signal<void, const user&> signal_subscribe_type;
00120         typedef sigc::signal<void, const user&> signal_unsubscribe_type;
00121 
00122         // TODO: Outsource subscribed users into an own class
00123         typedef std::list<user*>::size_type user_size_type;
00124         typedef ptr_iterator<
00125                 const user,
00126                 std::list<const user*>,
00127                 std::list<const user*>::const_iterator
00128         > user_iterator;
00129 
00130         typedef basic_buffer<document_type, selector_type> buffer_type;
00131         typedef typename buffer_type::net_type net_type;
00132 
00133         basic_document_info(const buffer_type& buffer,
00134                             net_type& net,
00135                             const user* owner, unsigned int id,
00136                             const std::string& title,
00137                             unsigned int suffix,
00138                             const std::string& encoding);
00139 
00140         basic_document_info(const buffer_type& buffer,
00141                             net_type& net,
00142                             const user* owner, unsigned int id,
00143                             const std::string& title,
00144                             const std::string& encoding);
00145 
00146         basic_document_info(const buffer_type& buffer,
00147                             net_type& net,
00148                             const serialise::object& obj);
00149 
00150         basic_document_info(const buffer_type& buffer,
00151                             net_type& net,
00152                             const net6::packet& init_pack);
00153 
00156         void serialise(serialise::object& obj) const;
00157 
00162         const user* get_owner() const;
00163 
00166         unsigned int get_owner_id() const;
00167 
00170         unsigned int get_id() const;
00171 
00174         const std::string& get_title() const;
00175 
00182         unsigned int get_suffix() const;
00183 
00187         std::string get_suffixed_title() const;
00188 
00191         const std::string& get_encoding() const;
00192 
00195         const Document& get_content() const;
00196 
00199         const privileges_table& get_privileges_table() const;
00200 
00203         virtual void insert(position pos, const std::string& text) = 0;
00204 
00207         virtual void erase(position pos, position len) = 0;
00208 
00212         virtual void rename(const std::string& new_title) = 0;
00213 
00216         virtual bool is_subscribed(const user& user) const;
00217 
00220         user_iterator user_begin() const;
00221 
00224         user_iterator user_end() const;
00225 
00228         user_size_type user_count() const;
00229 
00232         signal_rename_type rename_event() const;
00233 
00236         signal_subscribe_type subscribe_event() const;
00237 
00240         signal_unsubscribe_type unsubscribe_event() const;
00241 
00244         virtual void obby_session_close();
00245 
00248         virtual void obby_user_join(const user& user);
00249 
00252         virtual void obby_user_part(const user& user);
00253 
00254 protected:
00257         virtual void user_subscribe(const user& user);
00258 
00261         virtual void user_unsubscribe(const user& user);
00262 
00265         void document_rename(const std::string& title,
00266                              unsigned int suffix);
00267 
00270         void assign_document();
00271 
00274         void release_document();
00275 
00279         void session_close_impl();
00280 
00281         const buffer_type& m_buffer;
00282         net_type* m_net;
00283 
00284         const user* m_owner;
00285         unsigned int m_id;
00286         std::string m_title;
00287         unsigned int m_suffix;
00288         std::string m_encoding;
00289 
00290         std::auto_ptr<privileges_table> m_priv_table;
00291         std::auto_ptr<document_type> m_document;
00292         std::list<const user*> m_users;
00293 
00294         signal_rename_type m_signal_rename;
00295         signal_subscribe_type m_signal_subscribe;
00296         signal_unsubscribe_type m_signal_unsubscribe;
00297 
00298 public:
00301         const buffer_type& get_buffer() const;
00302 
00303 protected:
00307         net_type& get_net6();
00308 
00312         const net_type& get_net6() const;
00313 };
00314 
00315 template<typename Document, typename Selector>
00316 const typename basic_document_info<Document, Selector>::privileges
00317 basic_document_info<Document, Selector>::privileges::NONE =
00318 typename basic_document_info<Document, Selector>::privileges(0x00000000);
00319 
00320 template<typename Document, typename Selector>
00321 const typename basic_document_info<Document, Selector>::privileges
00322 basic_document_info<Document, Selector>::privileges::SUBSCRIBE =
00323 typename basic_document_info<Document, Selector>::privileges(0x00000001);
00324 
00325 template<typename Document, typename Selector>
00326 const typename basic_document_info<Document, Selector>::privileges
00327 basic_document_info<Document, Selector>::privileges::MODIFY =
00328 typename basic_document_info<Document, Selector>::privileges(0x00000002);
00329 
00330 template<typename Document, typename Selector>
00331 const typename basic_document_info<Document, Selector>::privileges
00332 basic_document_info<Document, Selector>::privileges::CLOSE =
00333 typename basic_document_info<Document, Selector>::privileges(0x00000004);
00334 
00335 template<typename Document, typename Selector>
00336 const typename basic_document_info<Document, Selector>::privileges
00337 basic_document_info<Document, Selector>::privileges::RENAME =
00338 typename basic_document_info<Document, Selector>::privileges(0x00000008);
00339 
00340 template<typename Document, typename Selector>
00341 const typename basic_document_info<Document, Selector>::privileges
00342 basic_document_info<Document, Selector>::privileges::ADMIN =
00343 typename basic_document_info<Document, Selector>::privileges(0x00000010);
00344 
00345 template<typename Document, typename Selector>
00346 const typename basic_document_info<Document, Selector>::privileges
00347 basic_document_info<Document, Selector>::privileges::ALL =
00348 typename basic_document_info<Document, Selector>::privileges(0xffffffff);
00349 
00352 template<typename Document, typename Selector>
00353 class basic_document_info<Document, Selector>::privileges_table
00354 {
00355 public:
00356         typedef sigc::signal<void, const user&, privileges>
00357                 signal_privileges_changed_type;
00358 
00363         privileges_table(privileges default_privileges);
00364 
00367         privileges get_default_privileges() const;
00368 
00371         privileges privileges_query(const user& user,
00372                                     privileges privs = privileges::ALL) const;
00373 
00376         void privileges_change(const user& user, privileges privs);
00377 
00381         signal_privileges_changed_type privileges_changed_event() const;
00382 protected:
00383         typedef std::map<const user*, privileges> priv_map;
00384 
00385         privileges m_default_privs;
00386         priv_map m_privs;
00387 
00388         signal_privileges_changed_type m_signal_privileges_changed;
00389 };
00390 
00391 } // namespace obby
00392 
00393 namespace serialise
00394 {
00395 
00396 // Default context - lookup by owner and ID
00397 template<typename DocumentInfo>
00398 class document_info_context_to: public context_base_to<DocumentInfo*>
00399 {
00400 public:
00401         typedef DocumentInfo* data_type;
00402 
00403         virtual std::string to_string(const data_type& from) const;
00404 protected:
00405         virtual void on_stream_setup(std::stringstream& stream) const;
00406 };
00407 
00408 template<typename Document, typename Selector>
00409 class default_context_to<obby::basic_document_info<Document, Selector>*>:
00410         public document_info_context_to<
00411                 obby::basic_document_info<Document, Selector>
00412         >
00413 {
00414 };
00415 
00416 template<typename Document, typename Selector>
00417 class default_context_to<const obby::basic_document_info<Document, Selector>*>:
00418         public document_info_context_to<
00419                 const obby::basic_document_info<Document, Selector>
00420         >
00421 {
00422 };
00423 
00424 template<typename DocumentInfo>
00425 class document_info_context_from: public context_base_from<DocumentInfo*>
00426 {
00427 public:
00428         typedef DocumentInfo* data_type;
00429         typedef typename DocumentInfo::buffer_type buffer_type;
00430 
00431         document_info_context_from(const buffer_type& buffer);
00432         virtual data_type from_string(const std::string& from) const;
00433 protected:
00434         virtual void on_stream_setup(std::stringstream& stream) const;
00435 
00436         const buffer_type& m_buffer;
00437 };
00438 
00439 template<typename DocumentInfo>
00440 class document_info_hex_context_from:
00441         public document_info_context_from<DocumentInfo>
00442 {
00443 public:
00444         typedef typename document_info_context_from<DocumentInfo>::buffer_type
00445                 buffer_type;
00446 
00447         document_info_hex_context_from(const buffer_type& buffer);
00448 protected:
00449         virtual void on_stream_setup(std::stringstream& stream) const;
00450 };
00451 
00452 template<typename Document, typename Selector>
00453 class default_context_from<obby::basic_document_info<Document, Selector>*>:
00454         public document_info_context_from<
00455                 obby::basic_document_info<Document, Selector>
00456         >
00457 {
00458 public:
00459         typedef typename document_info_context_from<
00460                 obby::basic_document_info<Document, Selector>
00461         >::buffer_type buffer_type;
00462 
00463         default_context_from(const buffer_type& buffer);
00464 };
00465 
00466 template<typename Document, typename Selector>
00467 class default_context_from<
00468         const obby::basic_document_info<Document, Selector>*
00469 >:
00470         public document_info_context_from<
00471                 const obby::basic_document_info<Document, Selector>
00472         >
00473 {
00474 public:
00475         typedef typename document_info_context_from<
00476                 const obby::basic_document_info<Document, Selector>
00477         >::buffer_type buffer_type;
00478 
00479         default_context_from(const buffer_type& buffer);
00480 };
00481 
00482 template<typename Document, typename Selector>
00483 class hex_context_from<obby::basic_document_info<Document, Selector>*>:
00484         public document_info_hex_context_from<
00485                 obby::basic_document_info<Document, Selector>
00486         >
00487 {
00488 public:
00489         typedef typename document_info_context_from<
00490                 obby::basic_document_info<Document, Selector>
00491         >::buffer_type buffer_type;
00492 
00493         hex_context_from(const buffer_type& buffer);
00494 };
00495 
00496 template<typename Document, typename Selector>
00497 class hex_context_from<const obby::basic_document_info<Document, Selector>*>:
00498         public document_info_hex_context_from<
00499                 const obby::basic_document_info<Document, Selector>
00500         >
00501 {
00502 public:
00503         typedef typename document_info_context_from<
00504                 const obby::basic_document_info<Document, Selector>
00505         >::buffer_type buffer_type;
00506 
00507         hex_context_from(const buffer_type& buffer);
00508 };
00509 
00510 template<typename DocumentInfo>
00511 std::string document_info_context_to<DocumentInfo>::
00512 	to_string(const data_type& from) const
00513 {
00514         std::stringstream stream;
00515         on_stream_setup(stream);
00516         stream << from->get_owner_id() << ' ' << from->get_id();
00517         return stream.str();
00518 }
00519 
00520 template<typename DocumentInfo>
00521 void document_info_context_to<DocumentInfo>::
00522 	on_stream_setup(std::stringstream& stream) const
00523 {
00524 }
00525 
00526 template<typename DocumentInfo>
00527 document_info_context_from<DocumentInfo>::
00528 	document_info_context_from(const buffer_type& buffer):
00529         m_buffer(buffer)
00530 {
00531 }
00532 
00533 template<typename DocumentInfo>
00534 typename document_info_context_from<DocumentInfo>::data_type
00535 document_info_context_from<DocumentInfo>::
00536 	from_string(const std::string& from) const
00537 {
00538         // Read document and owner id
00539         unsigned int owner_id, document_id;
00540         std::stringstream stream(from);
00541         on_stream_setup(stream);
00542         stream >> owner_id >> document_id;
00543 
00544         // Successful conversion?
00545         if(stream.bad() )
00546                 throw conversion_error("Document ID ought to be two integers");
00547 
00548         // Lookup document
00549         data_type info = m_buffer.document_find(owner_id, document_id);
00550 
00551         if(info == NULL)
00552         {
00553                 // No such document
00554                 obby::format_string str("Document ID %0%/%1% does not exist");
00555                 str << owner_id << document_id;
00556                 throw conversion_error(str.str() );
00557         }
00558 
00559         return info;
00560 }
00561 
00562 template<typename DocumentInfo>
00563 void document_info_context_from<DocumentInfo>::
00564 	on_stream_setup(std::stringstream& stream) const
00565 {
00566 }
00567 
00568 template<typename DocumentInfo>
00569 document_info_hex_context_from<DocumentInfo>::
00570 	document_info_hex_context_from(const buffer_type& buffer):
00571         document_info_context_from<DocumentInfo>(buffer)
00572 {
00573 }
00574 
00575 template<typename DocumentInfo>
00576 void document_info_hex_context_from<DocumentInfo>::
00577 	on_stream_setup(std::stringstream& stream) const
00578 {
00579         stream >> std::hex;
00580 }
00581 
00582 template<typename Document, typename Selector>
00583 default_context_from<obby::basic_document_info<Document, Selector>*>::
00584         default_context_from(const buffer_type& buffer):
00585         document_info_context_from<
00586                 obby::basic_document_info<Document, Selector>
00587         >(buffer)
00588 {
00589 }
00590 
00591 template<typename Document, typename Selector>
00592 default_context_from<const obby::basic_document_info<Document, Selector>*>::
00593         default_context_from(const buffer_type& buffer):
00594         document_info_context_from<
00595                 const obby::basic_document_info<Document, Selector>
00596         >(buffer)
00597 {
00598 }
00599 
00600 template<typename Document, typename Selector>
00601 hex_context_from<obby::basic_document_info<Document, Selector>*>::
00602         hex_context_from(const buffer_type& buffer):
00603         document_info_hex_context_from<
00604                 obby::basic_document_info<Document, Selector>
00605         >(buffer)
00606 {
00607 }
00608 
00609 template<typename Document, typename Selector>
00610 hex_context_from<const obby::basic_document_info<Document, Selector>*>::
00611         hex_context_from(const buffer_type& buffer):
00612         document_info_hex_context_from<
00613                 const obby::basic_document_info<Document, Selector>
00614         >(buffer)
00615 {
00616 }
00617 
00618 } // namespace serialise
00619 
00620 namespace obby
00621 {
00622 
00623 // Command context - lookup by document title
00624 template<typename DocumentInfo>
00625 class command_document_info_context_from:
00626         public ::serialise::context_base_from<DocumentInfo*>
00627 {
00628 public:
00629         typedef typename DocumentInfo::buffer_type buffer_type;
00630         typedef DocumentInfo* data_type;
00631 
00632         command_document_info_context_from(const buffer_type& buffer);
00633         virtual data_type from_string(const std::string& from) const;
00634 
00635 protected:
00636         const buffer_type& m_buffer;
00637 };
00638 
00639 template<typename Document, typename Selector>
00640 class command_context_from<obby::basic_document_info<Document, Selector>*>:
00641         public command_document_info_context_from<
00642                 obby::basic_document_info<Document, Selector>
00643         >
00644 {
00645 public:
00646         typedef typename command_document_info_context_from<
00647                 obby::basic_document_info<Document, Selector>
00648         >::buffer_type buffer_type;
00649 
00650         command_context_from(const buffer_type& buffer);
00651 };
00652 
00653 template<typename Document, typename Selector>
00654 class command_context_from<const obby::basic_document_info<Document, Selector>*>:
00655         public command_document_info_context_from<
00656                 const obby::basic_document_info<Document, Selector>
00657         >
00658 {
00659 public:
00660         typedef typename command_document_info_context_from<
00661                 const obby::basic_document_info<Document, Selector>
00662         >::buffer_type buffer_type;
00663 
00664         command_context_from(const buffer_type& buffer);
00665 };
00666 
00667 template<typename DocumentInfo>
00668 command_document_info_context_from<DocumentInfo>::
00669 	command_document_info_context_from(const buffer_type& buffer):
00670         m_buffer(buffer)
00671 {
00672 }
00673 
00674 template<typename DocumentInfo>
00675 typename command_document_info_context_from<DocumentInfo>::data_type
00676 command_document_info_context_from<DocumentInfo>::
00677 	from_string(const std::string& from) const
00678 {
00679         for(typename buffer_type::document_iterator iter =
00680                 m_buffer.document_begin();
00681             iter != m_buffer.document_end();
00682             ++ iter)
00683         {
00684                 if(iter->get_suffixed_title() == from)
00685                         return &(*iter);
00686         }
00687 
00688         throw ::serialise::conversion_error(
00689                 "Document with title " + from + " does not exist"
00690         );
00691 }
00692 
00693 template<typename Document, typename Selector>
00694 command_context_from<obby::basic_document_info<Document, Selector>*>::
00695         command_context_from(const buffer_type& buffer):
00696         command_document_info_context_from<
00697                 obby::basic_document_info<Document, Selector>
00698         >(buffer)
00699 {
00700 }
00701 
00702 template<typename Document, typename Selector>
00703 command_context_from<const obby::basic_document_info<Document, Selector>*>::
00704         command_context_from(const buffer_type& buffer):
00705         command_document_info_context_from<
00706                 const obby::basic_document_info<Document, Selector>
00707         >(buffer)
00708 {
00709 }
00710 
00711 // Document info implementation
00712 template<typename Document, typename Selector>
00713 basic_document_info<Document, Selector>::
00714 	basic_document_info(const buffer_type& buffer,
00715                             net_type& net,
00716                             const user* owner, unsigned int id,
00717                             const std::string& title,
00718                             unsigned int suffix,
00719                             const std::string& encoding):
00720         m_buffer(buffer), m_net(&net), m_owner(owner), m_id(id),
00721         m_title(title), m_suffix(suffix),
00722         m_encoding(encoding),
00723         m_priv_table(
00724                 new privileges_table(privileges::SUBSCRIBE | privileges::MODIFY)
00725         )
00726 {
00727 }
00728 
00729 template<typename Document, typename Selector>
00730 basic_document_info<Document, Selector>::
00731 	basic_document_info(const buffer_type& buffer,
00732                             net_type& net,
00733                             const user* owner, unsigned int id,
00734                             const std::string& title,
00735                             const std::string& encoding):
00736         m_buffer(buffer), m_net(&net), m_owner(owner), m_id(id),
00737         m_title(title), m_suffix(buffer.find_free_suffix(title, this)),
00738         m_encoding(encoding),
00739         m_priv_table(
00740                 new privileges_table(privileges::SUBSCRIBE | privileges::MODIFY)
00741         )
00742 {
00743 }
00744 
00745 template<typename Document, typename Selector>
00746 basic_document_info<Document, Selector>::
00747 	basic_document_info(const buffer_type& buffer,
00748                             net_type& net,
00749                             const serialise::object& obj):
00750         m_buffer(buffer), m_net(&net),
00751         m_owner(
00752                 obj.get_required_attribute("owner").
00753                         obby::serialise::attribute::as<const user*>(
00754                                 ::serialise::default_context_from<const user*>(
00755                                         buffer.get_user_table()
00756                                 )
00757                         )
00758         ),
00759         m_id(
00760                 obj.get_required_attribute("id").
00761                         obby::serialise::attribute::as<unsigned int>()
00762         ),
00763         m_title(
00764                 obj.get_required_attribute("title").
00765                         obby::serialise::attribute::as<std::string>()
00766         ),
00767         m_suffix(
00768                 obj.get_required_attribute("suffix").
00769                         obby::serialise::attribute::as<unsigned int>()
00770         ),
00771         m_encoding(
00772                 obj.get_required_attribute("encoding").
00773                         obby::serialise::attribute::as<std::string>()
00774         ),
00775         m_priv_table(
00776                 new privileges_table(privileges::SUBSCRIBE | privileges::MODIFY)
00777         )
00778 {
00779 }
00780 
00781 template<typename Document, typename Selector>
00782 basic_document_info<Document, Selector>::
00783 	basic_document_info(const buffer_type& buffer,
00784                             net_type& net,
00785                             const net6::packet& init_pack):
00786         m_buffer(buffer), m_net(&net),
00787         m_owner(
00788                 init_pack.get_param(0).net6::parameter::as<const user*>(
00789                         ::serialise::hex_context_from<const user*>(
00790                                 buffer.get_user_table()
00791                         )
00792                 )
00793         ),
00794         m_id(init_pack.get_param(1).net6::parameter::as<unsigned int>() ),
00795         m_title(init_pack.get_param(2).net6::parameter::as<std::string>() ),
00796         m_suffix(init_pack.get_param(3).net6::parameter::as<unsigned int>() ),
00797         m_encoding(init_pack.get_param(4).net6::parameter::as<std::string>() ),
00798         m_priv_table(
00799                 new privileges_table(privileges::SUBSCRIBE | privileges::MODIFY)
00800         )
00801 {
00802 }
00803 
00804 template<typename Document, typename Selector>
00805 void basic_document_info<Document, Selector>::
00806 	serialise(serialise::object& obj) const
00807 {
00808         /* Cannot serialise an object whose content we do not have */
00809         if(m_document.get() == NULL)
00810         {
00811                 throw std::logic_error(
00812                         "obby::basic_document_info::serialise:\n"
00813                         "No content available, probably not subscribed"
00814                 );
00815         }
00816 
00817         obj.add_attribute("owner").set_value(m_owner);
00818         obj.add_attribute("id").set_value(m_id);
00819         obj.add_attribute("title").set_value(m_title);
00820         obj.add_attribute("suffix").set_value(m_suffix);
00821         obj.add_attribute("encoding").set_value(m_encoding);
00822 
00823         for(typename document_type::chunk_iterator chunk_it =
00824                 m_document->chunk_begin();
00825             chunk_it != m_document->chunk_end();
00826             ++ chunk_it)
00827         {
00828                 serialise::object& chunk = obj.add_child();
00829                 chunk.set_name("chunk");
00830 
00831                 chunk.add_attribute("content").set_value(chunk_it.get_text() );
00832                 chunk.add_attribute("author").set_value(chunk_it.get_author() );
00833         }
00834 }
00835 
00836 template<typename Document, typename Selector>
00837 const user* basic_document_info<Document, Selector>::get_owner() const
00838 {
00839         return m_owner;
00840 }
00841 
00842 template<typename Document, typename Selector>
00843 unsigned int basic_document_info<Document, Selector>::get_owner_id() const
00844 {
00845         if(m_owner == NULL)
00846                 return 0;
00847 
00848         return m_owner->get_id();
00849 }
00850 
00851 template<typename Document, typename Selector>
00852 unsigned int basic_document_info<Document, Selector>::get_id() const
00853 {
00854         return m_id;
00855 }
00856 
00857 template<typename Document, typename Selector>
00858 const std::string& basic_document_info<Document, Selector>::get_title() const
00859 {
00860         return m_title;
00861 }
00862 
00863 template<typename Document, typename Selector>
00864 unsigned int basic_document_info<Document, Selector>::get_suffix() const
00865 {
00866         return m_suffix;
00867 }
00868 
00869 template<typename Document, typename Selector>
00870 std::string basic_document_info<Document, Selector>::get_suffixed_title() const
00871 {
00872         if(m_suffix != 1)
00873         {
00874                 format_string str("%0% (%1%)");
00875                 str << m_title << m_suffix;
00876                 return str.str();
00877         }
00878 
00879         return m_title;
00880 }
00881 
00882 template<typename Document, typename Selector>
00883 const std::string& basic_document_info<Document, Selector>::get_encoding() const
00884 {
00885         return m_encoding;
00886 }
00887 
00888 template<typename Document, typename Selector>
00889 const Document& basic_document_info<Document, Selector>::get_content() const
00890 {
00891         if(m_document.get() == NULL)
00892         {
00893                 throw std::logic_error(
00894                         "obby::basic_document_info::get_content:\n"
00895                         "No content available, probably not subscribed"
00896                 );
00897         }
00898 
00899         return *m_document;
00900 }
00901 
00902 template<typename Document, typename Selector>
00903 const typename basic_document_info<Document, Selector>::privileges_table&
00904 basic_document_info<Document, Selector>::get_privileges_table() const
00905 {
00906         return *m_priv_table;
00907 }
00908 
00909 template<typename Document, typename Selector>
00910 bool basic_document_info<Document, Selector>::
00911 	is_subscribed(const user& user) const
00912 {
00913         // TODO: Use std::set
00914         return std::find(
00915                 m_users.begin(),
00916                 m_users.end(),
00917                 &user
00918         ) != m_users.end();
00919 }
00920 
00921 template<typename Document, typename Selector>
00922 typename basic_document_info<Document, Selector>::user_iterator
00923 basic_document_info<Document, Selector>::user_begin() const
00924 {
00925         return m_users.begin();
00926 }
00927 
00928 template<typename Document, typename Selector>
00929 typename basic_document_info<Document, Selector>::user_iterator
00930 basic_document_info<Document, Selector>::user_end() const
00931 {
00932         return m_users.end();
00933 }
00934 
00935 template<typename Document, typename Selector>
00936 typename basic_document_info<Document, Selector>::user_size_type
00937 basic_document_info<Document, Selector>::user_count() const
00938 {
00939         return m_users.size();
00940 }
00941 
00942 template<typename Document, typename Selector>
00943 typename basic_document_info<Document, Selector>::signal_rename_type
00944 basic_document_info<Document, Selector>::rename_event() const
00945 {
00946         return m_signal_rename;
00947 }
00948 
00949 template<typename Document, typename Selector>
00950 typename basic_document_info<Document, Selector>::signal_subscribe_type
00951 basic_document_info<Document, Selector>::subscribe_event() const
00952 {
00953         return m_signal_subscribe;
00954 }
00955 
00956 template<typename Document, typename Selector>
00957 typename basic_document_info<Document, Selector>::signal_unsubscribe_type
00958 basic_document_info<Document, Selector>::unsubscribe_event() const
00959 {
00960         return m_signal_unsubscribe;
00961 }
00962 
00963 template<typename Document, typename Selector>
00964 void basic_document_info<Document, Selector>::obby_session_close()
00965 {
00966         session_close_impl();
00967 }
00968 
00969 template<typename Document, typename Selector>
00970 void basic_document_info<Document, Selector>::obby_user_join(const user& user)
00971 {
00972 }
00973 
00974 template<typename Document, typename Selector>
00975 void basic_document_info<Document, Selector>::obby_user_part(const user& user)
00976 {
00977         // User left the session: Unsubscribe from document
00978         if(is_subscribed(user) )
00979                 user_unsubscribe(user);
00980 }
00981 
00982 template<typename Document, typename Selector>
00983 void basic_document_info<Document, Selector>::user_subscribe(const user& user)
00984 {
00985         if(is_subscribed(user) )
00986         {
00987                 throw std::logic_error(
00988                         "obby::basic_document_info::user_subscribe:\n"
00989                         "User is already subscribed"
00990                 );
00991         }
00992 
00993         m_users.push_back(&user);
00994         m_signal_subscribe.emit(user);
00995 }
00996 
00997 template<typename Document, typename Selector>
00998 void basic_document_info<Document, Selector>::user_unsubscribe(const user& user)
00999 {
01000         if(!is_subscribed(user) )
01001         {
01002                 throw std::logic_error(
01003                         "obby::basic_document_info::user_unsubscribe:\n"
01004                         "User is not subscribed"
01005                 );
01006         }
01007 
01008         m_users.erase(
01009                 std::remove(m_users.begin(), m_users.end(), &user),
01010                 m_users.end()
01011         );
01012 
01013         m_signal_unsubscribe.emit(user);
01014 }
01015 
01016 template<typename Document, typename Selector>
01017 void basic_document_info<Document, Selector>::
01018 	document_rename(const std::string& title,
01019                         unsigned int suffix)
01020 {
01021         m_title = title;
01022         m_suffix = suffix;
01023 
01024         m_signal_rename.emit(title);
01025 }
01026 
01027 template<typename Document, typename Selector>
01028 void basic_document_info<Document, Selector>::assign_document()
01029 {
01030         // TODO: Document template given to buffer that may be copied here.
01031         // TODO: Give only user table to document
01032         m_document.reset(new Document(get_buffer().get_document_template() ));
01033 }
01034 
01035 template<typename Document, typename Selector>
01036 void basic_document_info<Document, Selector>::release_document()
01037 {
01038         m_document.reset(NULL);
01039 }
01040 
01041 template<typename Document, typename Selector>
01042 void basic_document_info<Document, Selector>::session_close_impl()
01043 {
01044         // Drop network reference
01045         m_net = NULL;
01046 }
01047 
01048 template<typename Document, typename Selector>
01049 const typename basic_document_info<Document, Selector>::buffer_type&
01050 basic_document_info<Document, Selector>::get_buffer() const
01051 {
01052         return m_buffer;
01053 }
01054 
01055 template<typename Document, typename Selector>
01056 typename basic_document_info<Document, Selector>::net_type&
01057 basic_document_info<Document, Selector>::get_net6()
01058 {
01059         if(m_net == NULL)
01060         {
01061                 throw std::logic_error(
01062                         "obby::basic_document_info::::get_net6:\n"
01063                         "No network object available. Most probably the "
01064                         "session has been closed"
01065                 );
01066         }
01067 
01068         return *m_net;
01069 }
01070 
01071 template<typename Document, typename Selector>
01072 const typename basic_document_info<Document, Selector>::net_type&
01073 basic_document_info<Document, Selector>::get_net6() const
01074 {
01075         if(m_net == NULL)
01076         {
01077                 throw std::logic_error(
01078                         "obby::basic_document_info::::get_net6:\n"
01079                         "No network object available. Most probably the "
01080                         "session has been closed"
01081                 );
01082         }
01083 
01084         return *m_net;
01085 }
01086 
01087 // privileges_table
01088 template<typename Document, typename Selector>
01089 basic_document_info<Document, Selector>::privileges_table::
01090 	privileges_table(privileges default_privileges):
01091         m_default_privs(default_privileges)
01092 {
01093 }
01094 
01095 template<typename Document, typename Selector>
01096 typename basic_document_info<Document, Selector>::privileges
01097 basic_document_info<Document, Selector>::privileges_table::
01098 	get_default_privileges() const
01099 {
01100         return m_default_privs;
01101 }
01102 
01103 template<typename Document, typename Selector>
01104 typename basic_document_info<Document, Selector>::privileges
01105 basic_document_info<Document, Selector>::privileges_table::
01106 	privileges_query(const user& user, privileges privs) const
01107 {
01108         typename priv_map::const_iterator iter = m_privs.find(&user);
01109         if(iter == m_privs.end() ) return m_default_privs & privs;
01110         return iter->second & privs;
01111 }
01112 
01113 template<typename Document, typename Selector>
01114 void basic_document_info<Document, Selector>::privileges_table::
01115 	privileges_change(const user& user, privileges privs)
01116 {
01117         m_privs[&user] = privs;
01118         m_signal_privileges_changed.emit(user, privs);
01119 }
01120 
01121 template<typename Document, typename Selector>
01122 typename basic_document_info<Document, Selector>::privileges_table::
01123         signal_privileges_changed_type
01124 basic_document_info<Document, Selector>::privileges_table::
01125 	privileges_changed_event() const
01126 {
01127         return m_signal_privileges_changed;
01128 }
01129 
01130 } // namespace obby
01131 
01132 #endif // _OBBY_DOCUMENT_INFO_HPP_

Generated on Fri Jan 11 10:01:32 2008 for obby by  doxygen 1.5.1