/* libobby - Network text editing library
* Copyright (C) 2005, 2006 0x539 dev group
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _OBBY_OPERATION_HPP_
#define _OBBY_OPERATION_HPP_
#include <net6/non_copyable.hpp>
#include <net6/packet.hpp>
#include "position.hpp"
#include "user.hpp"
namespace obby
{
/** An operation describes a change in the document.
*/
template<typename Document>
class operation: private net6::non_copyable
{
public:
typedef Document document_type;
/** Creates a copy of this operation.
*/
virtual operation* clone() const = 0;
/** Creates the reverse operation of this one.
* @param doc Document to receive additional information from.
*/
virtual operation* reverse(const document_type& doc) const = 0;
/** Applies this operation to a document.
* @param doc Document to apply this operation to.
* @param author User who performed this operation.
*/
virtual void apply(document_type& doc, const user* author) const = 0;
/** Transforms <em>base_op</em> against this operation.
*/
virtual operation* transform(const operation& base_op) const = 0;
/** Includes the effect of the given insertion into this operation.
*/
virtual operation* transform_insert(position pos,
const std::string& text) const = 0;
/** Includes the effect of the given deletion into this operation.
*/
virtual operation* transform_delete(position pos,
position len) const = 0;
/** Appends this operation to the given packet.
*/
virtual void append_packet(net6::packet& pack) const = 0;
/** Reads an operation from the given packet.
* @param pack Packet to read from.
* @param index From which parameter to read at.
* @param user_table User table were to read potential user
* information from.
*/
static std::auto_ptr<operation>
from_packet(const net6::packet& pack,
unsigned int& index,
const user_table& user_table);
protected:
};
template<typename Document>
class no_operation;
template<typename Document>
class split_operation;
template<typename Document>
class insert_operation;
template<typename Document>
class delete_operation;
template<typename Document>
class reversible_insert_operation;
template<typename Document>
std::auto_ptr<operation<Document> >
operation<Document>::from_packet(const net6::packet& pack,
unsigned int& index,
const user_table& user_table)
{
const std::string& type =
pack.get_param(index ++).net6::parameter::as<std::string>();
std::auto_ptr<operation<Document> > op;
if(type == "ins")
{
op.reset(new insert_operation<Document>(pack, index) );
}
else if(type == "del")
{
op.reset(new delete_operation<Document>(pack, index) );
}
else if(type == "split")
{
op.reset(
new split_operation<Document>(
pack,
index,
user_table)
);
}
else if(type == "noop")
{
op.reset(new no_operation<Document>(pack, index) );
}
/* else if(type == "revins")
{
op.reset(
new reversible_insert_operation<Document>(
pack,
index,
user_table
)
);
}*/
else
{
throw net6::bad_value("Unexpected record type: " + type);
}
return op;
}
} // namespace obby
#endif // _OBBY_OPERATION_HPP_
syntax highlighted by Code2HTML, v. 0.9.1