1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2052 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 //
19 // to contact the author : http://dar.linux.free.fr/email.html
20 /*********************************************************************/
21 
22     /// \file messaging.hpp
23     /// \brief messaging_decode and messaging_encode are used to insert messages in a flow if data blocks
24     /// \ingroup Private
25     ///
26 
27 
28 #ifndef MESSAGING_HPP
29 #define MESSAGING_HPP
30 
31 #include "../my_config.h"
32 
33 #include <string>
34 
35 #include "label.hpp"
36 #include "infinint.hpp"
37 #include "memory_file.hpp"
38 #include "infinint.hpp"
39 
40 namespace libdar
41 {
42 
43     enum class msg_type
44     {
45 	unset,                    //< no argument: message type is not set (error)
46 	order_read_ahead,         //< + infinint : messge is an info that the given amount of data is about to be read
47 	order_read_ahead_begin,   //< + infinint : message continues with the next block
48 	order_read,               //< + U_I      : message is a read order (with expected size to be read ahead)
49 	order_sync_write,         //< no argument: order to flush all pending writes
50 	answr_sync_write_done,    //< no argument: answer from the slave that all data have been sync written
51 	order_skip,               //< + infinint : message is an order to seek at given position
52 	order_skip_begin,         //< + infinint : message is an order to seek but the seek info continues in the next message
53 	order_skip_to_eof,        //< no argument: message requesting slave to skip to end of file
54 	order_skip_fwd,           //< + U_I      : order to skip foward
55 	order_skip_bkd,           //< + U_I      : order to skip backward
56 	answr_skip_done,          //< + bool     : answer for all kind of skip orders
57 	order_skippable_fwd,      //< + infinint : message from master containing a skippable forward request info
58 	order_skippable_fwd_begin,//< + infinint : message continues on the next block
59 	order_skippable_bkd,      //< + infinint : message from master containing a skippable backward request info
60 	order_skippable_bkd_begin,//< + infinint : message continues on the next block
61 	answr_skippable,          //< + bool     : answer from slace to a skippable forward/backward request
62 	order_get_position,       //< no argument: order to get the current position in file
63 	answr_position,           //< + infinint : answer with the current position
64 	answr_position_begin,     //< + infinint : message continues with the next block
65 	answr_exception,          //< no argument: last operation generated an exception for at slave side, slave has probably died after that
66 	order_end_of_xmit,        //< no argument: message is the last message and implies freedom of the slave
67         order_stop_readahead,     //< no argument: order to stop possibly running read_ahead
68 	answr_readahead_stopped,  //< no argument: answer that the readahead has ended or no read ahead was running
69 	order_wakeup,             //< no argument: order to continue reading/writing loop (reading suspendend because of pipe full, writing because of pipe was empty)
70 	data_partial,             //< + data     : beside data in input/output data pipes
71 	data_completed            //< + data     : beside data in output data pipe when EOF has been reached
72     };
73 
74     extern bool msg_equivalent(msg_type arg1, msg_type arg2);
75     extern bool msg_continues(msg_type msg);
76     extern char msg_type2char(msg_type x);
77     extern msg_type char2msg_type(char x);
78     extern msg_type msg_continuation_of(msg_type x);
79 
80 
81     class messaging_decode : public on_pool
82     {
83     public:
messaging_decode()84 	messaging_decode() {msgt = msg_type::unset; };
85 
86 	    /// reset the object to its initial state
87 	void clear();
88 
89 	    /// add a block of data to be decoded
90 	    ///
91 	    /// \param[in] x_input is the address of the message to add
92 	    /// \param[in] x_size is the size of the message to add
93 	    /// \return true if the message is complet, false if a new block
94 	    /// need to be added with this call in order to decode the message
95 	bool add_block(const char *x_input, U_I x_size);
96 
97 	    /// get the type of message pointed to at construction time
get_type() const98 	msg_type get_type() const { return msgt; };
99 
100 	    /// for messages of type order_skip, answr_filesize, order_read_ahead, answr_filesize,
101 	infinint get_infinint() const;
102 
103 	    /// for messages of type order_read
104 	U_I get_U_I() const;
105 
106 	    /// for messages of type order_set_context
107 	std::string get_string() const;
108 
109 	    /// for messages of type anwsr_oldarchive
110 	bool get_bool() const;
111 
112 	    /// for messages of type answr_get_dataname,
113 	label get_label() const;
114 
115     private:
116 	msg_type msgt;
117 	memory_file buffer;
118 
119     };
120 
121 
122     class messaging_encode : public on_pool
123     {
124     public:
125 	    /// constructor
messaging_encode()126 	messaging_encode() { msgt = msg_type::unset; };
127 
128 	    /// reset the object to its initial state
129 	void clear();
130 
131 	    /// define the type of the message to generate
set_type(msg_type val)132 	void set_type(msg_type val) { msgt = val; };
133 
134 	    /// add infininit attribute
135 	void set_infinint(const infinint & val);
136 
137 	    /// add U_I attribute
138 	void set_U_I(U_I val);
139 
140 	    /// add string attribute
141 	void set_string(const std::string & val);
142 
143 	    /// set boolean attribute
144 	void set_bool(bool val);
145 
146 	    /// set label attribute
147 	void set_label(const label & val);
148 
149 	    /// set the read block pointer to the first block
150 	void reset_get_block();
151 
152 	    /// read the next block
153 	    ///
154 	    /// \param[in] ptr is the address where to write the next block of the message
155 	    /// \param[in,out] size is the maximum amount of byte that can be written to ptr
156 	    /// and is modified by this call to the effective number of byte written to ptr
157 	    /// \return true if the whole message could be written to block, else false
158 	    /// is returned an a new call to get_block is necessary to write down the rest of
159 	    /// the message up to the time get_block() returns true
160 	    /// \note for data encoding, the message is a single byte length.
161 	    /// this byte has been placed before the data before in the same block
162 	bool get_block(char * ptr, unsigned int & size);
163 
164     private:
165 	msg_type msgt;
166 	memory_file buffer;
167 
168     };
169 
170 
171 } // end of namespace
172 
173 #endif
174