Libdoclone v0.7.0

===============================================================================
Using the C and C++ APIs for libdoclone.
===============================================================================

CONTENTS
--------

1	Using the C API
2	Using the C++ API
3	Author

Copyright (C)  2013 Joan Lledó.
Permission is granted to copy, distribute and/or modify this text under
the terms of the Creative Commons Attribution-ShareAlike 3.0 Unported License.
You can read the entire license following this link:
http://creativecommons.org/licenses/by-sa/3.0/

-------------------------------------------------------------------------------
1	Using the C API:
-------------------------------------------------------------------------------

The main type of the C API is the dc_doclone struct. his struct provides a
way for calling the methods of libdoclone from a C program. To create an object,
the function doclone_new() must be called by this way:

	dc_doclone *dc_obj = doclone_new();

After using a dc_doclone object, its memory can be freed by calling:

	doclone_destroy(dc_obj);

It is possible to subscribe the events of the library. These can be used to
know the operations progress and possible incidences.
To do this, some functions must be implemented with the proper prototype.

First of all, These are the four kinds of libdoclone events:

	- The transfer events:
		Events that inform about the process of read/write or send/receive of
		data. There're only two transfer events: The TRANSFERRED_BYTES event and
		the TOTAL_SIZE event.
		
		The TRANSFERRED_BYTES can be raised lot of times in the execution of the
		program, and informs about the amount of bytes transferred until now.
		
		The TOTAL_SIZE only is raised once in the execution time, when the
		library has determined the total amount of bytes that should be
		transferred. This can be useful for creating a progress bar.
	
	- The operation events:
		One operation is one action that the library will perform. There are
		many operations, such as reading partition table of a disc, writing the
		uuid of a file system, installing GRUB, etc. This king of events can
		have two states: Pending or Completed. The library can add new pending
		operations and mark them as completed during the execution time.
	
	- The general events:
		These are simple events that can happen during the program execution,
		such as receiving a connection from other libdoclone instance or
		interrupting the program by order of the user.
		
	- The notification of the exceptions:
		In case of something doesn't work as expected, for example, when the
		library tries to write in a folder which access is denied or in case of
		connection error, then the library raises an exception until the highest
		level of the calling hierarchy. Since C doesn't support exceptions, all
		of them are captured by the library, but their error messages are sent
		to the listening views.
		
Subscribing to any of these events can be performed by calling one of the
following functions:

	- doclone_subscribe_to_tranfer_events(dc_doclone *dc_obj, transferCallback call);
	- doclone_subscribe_to_operation_events(dc_doclone *dc_obj, operationCallback call);
	- doclone_subscribe_to_general_events(dc_doclone *dc_obj, generalCallback call);
	- doclone_subscribe_to_notifications(dc_doclone *dc_obj, notificationCallback call);
	
All these functions receive a pointer to the dc_doclone object as first
parameter, and a pointer to a callback function as second. The callback
function passed as parameter must have the proper prototype. These prototypes
are specified by some defined types:
	
	- transferCallback:  void (*transferCallback) (dcTransferEvent event, uint64_t numBytes);
	
	- operationCallback: void (*operationCallback) (dcOperationEvent event, dcOperationType type, const char *target);
	
	- generalCallback: void (*generalCallback) (dcEvent event, const char *target);
	
	- notificationCallback void (*notificationCallback) (const char *str);
	
Note that dcTransferEvent, dcOperationEvent, dcOperationType and dcEvent are
just a C wrapper for Doclone::dcTransferEvent, Doclone::dcOperationEvent,
Doclone::dcOperationType and Doclone::dcEvent enums of the library.
	
After declaring one function with the proper prototype, it is possible to
use it as callback to listen the library events, for example:

	void notify(const char *str) {
		dprintf(2, "%s\n", str);
	}

	...
	
	doclone_subscribe_to_notifications(dc_obj, &notify);
	
By this way it can listen to all the events of the library:

	doclone_subscribe_to_tranfer_events(dc_obj, &notifyTransfer);
	doclone_subscribe_to_operation_events(dc_obj, &notifyOperation);
	doclone_subscribe_to_general_events(dc_obj, &notifyGeneral);
	doclone_subscribe_to_notifications(dc_obj, &notify);
	
The next step is to set all the dc_doclone object required properties before
performing the work. These are:

	- image (char*): It is the image file path to work with
	- device (char*): The device path to be read or written
	- address (char*): the IP address of the server
	- nodes number (int): The number of receivers
	- empty (int): Read/write the data or just clone the partitions table (true or false)
	- force (int): Force working even if the image doesn't fit in the destination device (true or false)

These are some functions for configuring those properties:

	- void doclone_set_image(dc_doclone *dc_obj, const char *image);
	- void doclone_set_device(dc_doclone *dc_obj, const char *device);
	- void doclone_set_address(dc_doclone *dc_obj, const char *address);
	- void doclone_set_nodes_number(dc_doclone *dc_obj, unsigned int number);
	- void doclone_set_empty(dc_doclone *dc_obj, unsigned short empty);
	- void doclone_set_force(dc_doclone *dc_obj, unsigned short force);

The last step is to call one of the functions that perform the work:

	- int doclone_create(const dc_doclone *dc_obj);
	- int doclone_restore(const dc_doclone *dc_obj);
	- int doclone_send(const dc_doclone *dc_obj);
	- int doclone_receive(const dc_doclone *dc_obj);
	- int doclone_chain_origin(const dc_doclone *dc_obj);
	- int doclone_chain_link(const dc_doclone *dc_obj);

All of these functions receive a pointer to a dc_doclone object which
attributes must be properly set, and return 0 if everything is OK, or -1 if
something has failed.

These are some examples of use:

	- Creating or restoring an image of/into a device:
		- Set the image and the device of the dc_doclone object:
		
			doclone_set_image(dc_obj, "/home/user/image.doclone");
			doclone_set_device(dc_obj, "/dev/sdb");
			
		- Then call the create function:
		
			doclone_create(dc_obj);
			
		- Or the restore function:
			
			doclone_restore(dc_obj);
		
	- Sending an image over network:
		- For the server, set the number of receivers and the image to read.
		
			doclone_set_nodes_number(dc_obj, 1);
			doclone_set_image(dc_obj, "/home/user/image.doclone");
		
		- Then call the send function:
		
			doclone_send(dc_obj);
	
	- For the client, set the server IP address and the device to write:
		
			doclone_set_address(dc_obj, "192.168.0.10");
			doclone_set_device(dc_obj, "/dev/sdb");
			
			doclone_receive(dc_obj);

			
-------------------------------------------------------------------------------
2	Using the C++ API:
-------------------------------------------------------------------------------

The main type of the C++ API is the Clone class. This class provides a way
for calling the methods of libdoclone from a C++ program. To create an object,
the static method getInstance() must be called by this way:

	Doclone::doclone *dcl = Doclone::Clone::getInstance();

It is possible to subscribe the events of the library. These can be used to know
the operations progress and possible incidences. To do this, some functions must
be implemented with the proper prototype.
 
First of all, These are the four kinds of libdoclone events:

	- The transfer events:
		Events that inform about the process of read/write or send/receive of
		data. There're only two transfer events: The TRANSFERRED_BYTES event and
		the TOTAL_SIZE event.
		
		The TRANSFERRED_BYTES can be raised lot of times in the execution of the
		program, and informs about the amount of bytes transferred until now.
		
		The TOTAL_SIZE only is raised once in the execution time, when the
		library has determined the total amount of bytes that should be
		transferred. This can be useful for creating a progress bar.
	
	- The operation events:
		One operation is one action that the library will perform. There are
		many operations, such as reading partition table of a disc, writing the
		uuid of a file system, installing GRUB, etc. This king of events can
		have two states: Pending or Completed. The library can add new pending
		operations and mark them as completed during the execution time.
	
	- The general events:
		These are simple events that can happen during the program execution,
		such as receiving a connection from other libdoclone instance or
		interrupting the program by order of the user.
		
	- The notification of the exceptions:
		In case of something doesn't work as expected, for example, when the
		library tries to write in a folder which access is denied or in case of
		connection error, then the library raises an exception until the highest
		level of the calling hierarchy. Since C doesn't support exceptions, all
		of them are captured by the library, but their error messages are sent
		to the listening views.
		
Subscribing to any of these events can be performed by extending the
Doclone::AbstractObserver class and overriding all its notify() methods:

	- void notify(Doclone::dcTransferEvent event, uint64_t numBytes);
	- void notify(Doclone::dcOperationEvent event, 
		Doclone::dcOperationType type, const std::string &target);
	- void notify(Doclone::dcEvent event, const std::string &target);
	- void notify(const std::string &str);
	
For example:
	
	class MyObserver : public Doclone::AbstractObserver {
	public:
		MyObserver();
	
		void notify(Doclone::dcTransferEvent event, uint64_t numBytes);
		void notify(Doclone::dcOperationEvent event,
				Doclone::dcOperationType type, const std::string &target);
		void notify(Doclone::dcEvent event, const std::string &target);
		void notify(const std::string &str);
	};
	
	void MyObserver::notify(const std::string &str) {
		std::cerr << "Something has happened:" << " " << str << std::endl;
	}

The next step is to set all the doclone object required properties before
performing the work. These are:

	- image (char*): It is the image file path to work with
	- device (char*): The device path to be read or written
	- address (char*): the IP address of the server
	- nodes number (int): The number of receivers
	- empty (int): Read/write the data or just clone the partitions table (true or false)
	- force (int): Force working even if the image doesn't fit in the destination device (true or false)

These are some setters for configuring the properties:

	- void setEmpty(bool empty);
	- void setNodesNumber(unsigned int nodesNum);
	- void setDevice(const std::string &device);
	- void setImage(const std::string &image);
	- void setAddress(const std::string &address);
	- void setForce(bool force);

The last step is to call one of the methods that perform the work:

	- void create() throw(Exception);
	- void restore() throw(Exception);
	- void send() throw(Exception);
	- void receive() throw(Exception);
	- void chainOrigin() throw(Exception);
	- void chainLink() throw(Exception);

All this methods raise an exception if anything goes wrong. The library has
two kinds of exceptions, the Warning Exceptions and the Error Exceptions. The
Warning Exceptions don't stop the execution and are captured in the library,
but their messages are sent to the views. These messages are received by the
views with "void notify(const std::string &str)" method override. The Error
Exceptions are defined for severe errors, these ones always stop the
execution and are raised to the caller. The library user must decide what to
do with them.

There are some examples of use:

	- Creating or restoring an image of/into a device:
		- Set the image and the device on the doclone object:
		
			Doclone::doclone *dcl = Doclone::doclone::getInstace();
			
			dcl->setImage("/home/user/image.doclone");
			dcl->setDevice("/dev/sdf");
			
		- Then call the create function:
		
			try {
				dcl->create();
			} catch (const Doclone::Exception &ex) {
				// Do something
			}
			
		- Or call the restore function:
			
			try {
				dcl->restore();
			} catch (const Doclone::Exception &ex) {
				// Do something
			}
		
	- Sending an image over network:
		- For the server, set the number of receivers and the image to read.
		
			dcl->setNodesNumber(1);
			dcl->setImage("/home/user/image.doclone");
		
		- Then call the send function:
		
			try {
				dcl->send();
			} catch (const Doclone::Exception &ex) {
				// Do something
			}
	
	- For the client, set the server IP address and the device to write:
		
			dcl->setAddress("192.168.0.10");
			dcl->setDevice("/dev/sdb");
			
			try {
				dcl->receive();
			} catch (const Doclone::Exception &ex) {
				// Do something
			}

-------------------------------------------------------------------------------
 4 Author
-------------------------------------------------------------------------------
libdoclone has written by Joan Lledó <joanlluislledo@gmail.com>

